Add dropdown and additional info fields to form steps

Updated form interfaces to include optional dropdown and additional info properties. Adjusted form rendering logic to handle these new fields, providing clearer instructions and choices for users. Refined validation messages for consistency and clarity.
This commit is contained in:
Teriuihi 2024-08-08 20:33:15 +02:00
parent 7407372b03
commit 94c336fb74
3 changed files with 69 additions and 29 deletions

View File

@ -34,6 +34,10 @@ export const apply: FormData = {
min_length: 2,
max_length: 3,
required: true,
additional_info: "Use voice chat in Discord with reasonable audio quality\n" +
"Take screenshots through your pc (normally f2 in minecraft)\n" +
"Record your screen through your pc at 20fps+ and 720p+ at normal Minecraft settings (with free programs like OBS)\n",
drop_down: ["Yes", "No", ""],
},
{
label: "What is your age?",
@ -134,23 +138,23 @@ export const apply: FormData = {
.min(3, 'Username should be at least 3 characters')
.max(16, 'Username should not exceed 16 characters')
.matches(/^[a-zA-Z0-9_]*$/, 'Username should only include alphanumeric characters and underscore')
.required('Username is required'),
.required('Please enter your username'),
email: Yup.string()
.email('Invalid email')
.min(3, 'Email should be at least 3 characters')
.max(254, 'Email should not exceed 254 characters')
.required(),
.required('Please enter your email'),
discord: Yup.string()
.min(2, 'Discord name should be at least 2 characters')
.max(32, 'Discord name should be at most 32 characters')
.matches(/^(?!.*\.\.)([a-z0-9._]{2,32})$/, 'Please enter a valid Discord name')
.required('Discord name is required'),
.required('Please enter your Discord name'),
pc_requirements: Yup.string()
.min(2, "Please answer yes or no")
.max(3, "Please answer yes or no")
// .min(2, "Please answer yes or no")
// .max(3, "Please answer yes or no")
.matches(/(yes|no)$/i, 'Yes or no')
.required('An answer is required'),
@ -166,39 +170,40 @@ export const apply: FormData = {
.required('Your join date is required, if you\'re not sure enter an estimated date'),
avg_time: Yup.number()
.typeError('Please enter a number')
.min(0, 'Please enter a positive number')
.max(168, 'There are only 168 hours in a week')
.required(),
.required('Please enter the average time you will be available each week'),
available_days: Yup.string()
.min(6, 'Please provide at least 6 characters')
.max(128, 'Please provide at most 128 characters')
.required('Available days are required'),
.required('Please enter your available days are required'),
available_time: Yup.string()
.min(3, 'Please provide at least 3 characters')
.max(256, 'Please provide at most 256 characters')
.required('Available time is required'),
.required('Please enter your available time'),
staff_experience: Yup.string()
.min(2, 'Please provide your experience as staff, if you don\'t have any you can say that instead')
.max(2000, 'Please provide at most 2000 characters')
.required('Staff experience is required'),
.required('Please enter your staff experience or simply say you don\'t have any'),
plugin_experience: Yup.string()
.min(2, 'Please provide your experience with moderation plugins, if you don\'t have any you can say that instead')
.max(2000, 'Please provide at most 2000 characters')
.required('Plugin experience is required'),
.required('Please enter your plugin experience or simply say you don\'t have any'),
why_staff: Yup.string()
.min(2, 'Please provide your reason for wanting to be a moderator')
.max(2000, 'Please provide at most 2000 characters')
.required('Reason for wanting to be a moderator is required'),
.required('Please enter your reason for wanting to be a moderator on Altitude'),
expectations_mod: Yup.string()
.min(2, 'Please provide your expectations of a moderator')
.max(2000, 'Please provide at most 2000 characters')
.required('Expectations of a moderator is required'),
.required('Please enter your expectations of what a moderator does'),
other: Yup.string()
.max(2000, 'Please provide at most 2000 characters')

View File

@ -11,6 +11,8 @@ export interface Step {
min_length: number;
max_length: number;
required: boolean;
additional_info?: string;
drop_down?: string[]
}
export interface UserInput {
@ -21,7 +23,7 @@ export type FormData = {
steps: Step[];
backend: string;
userInput: UserInput;
spec: Yup.Schema<any>
spec: Yup.Schema<any>;
title: string;
}

View File

@ -82,22 +82,55 @@ const GenericForm = (formData: FormData) => {
<Form>
<div>
<label>
{steps[currentStep].label}
<Field
type={steps[currentStep].type}
name={steps[currentStep].name}
required={steps[currentStep].required}
min={steps[currentStep].min_length}
max={steps[currentStep].max_length}
as={(steps[currentStep].type === "textarea") ? "textarea" : "input"}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
handleChange(e);
if (prevLength !== values[steps[currentStep].name].length) {
setFieldTouched(steps[currentStep].name);
setPrevLength(values[steps[currentStep].name].length);
}
}}
/>
<label>
{steps[currentStep].label}
</label>
<label>
{
steps[currentStep].additional_info ?
steps[currentStep].additional_info?.split('\n').map((line, i) => (
<React.Fragment key={i}>{line}<br/></React.Fragment>
))
: null
}
</label>
</label>
<label>
{
steps[currentStep].drop_down ? (
<Field as="select"
name={steps[currentStep].name}
onChange={(e: React.ChangeEvent<HTMLSelectElement>) => {
handleChange(e);
if (prevLength !== values[steps[currentStep].name].length) {
setFieldTouched(steps[currentStep].name);
setPrevLength(values[steps[currentStep].name].length);
}
}}>
{steps[currentStep].drop_down?.map((option, i) => (
<option key={i} value={option}>
{option}
</option>
))}
</Field>
) : (
<Field
type={steps[currentStep].type}
name={steps[currentStep].name}
required={steps[currentStep].required}
min={steps[currentStep].min_length}
max={steps[currentStep].max_length}
as={(steps[currentStep].type === "textarea") ? "textarea" : "input"}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
handleChange(e);
if (prevLength !== values[steps[currentStep].name].length) {
setFieldTouched(steps[currentStep].name);
setPrevLength(values[steps[currentStep].name].length);
}
}}
/>
)
}
<ErrorMessage name={steps[currentStep].name} component="div"/>
</label>
</div>