Skip to content

Commit

Permalink
Merge pull request #1485 from Spiteless/ts.1482.validated_text_field
Browse files Browse the repository at this point in the history
Create ValidatedTextField
  • Loading branch information
trillium authored Aug 29, 2023
2 parents a2fffb2 + aa6d7e8 commit c006b27
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 73 deletions.
88 changes: 15 additions & 73 deletions client/src/components/ProjectForm.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import React, { useState } from 'react';
import { Link, useHistory } from 'react-router-dom';
import { useForm } from 'react-hook-form';
import ProjectApiService from '../api/ProjectApiService';

import { ReactComponent as EditIcon } from '../svg/Icon_Edit.svg';
import { ReactComponent as PlusIcon } from '../svg/PlusIcon.svg';
import { Redirect } from 'react-router-dom';
import {
Typography,
Box,
Divider,
TextField,
InputLabel,
Button,
Grid,
Radio,
Expand All @@ -20,7 +14,12 @@ import {
RadioGroup,
} from '@mui/material';
import { styled } from '@mui/material/styles';

import useAuth from '../hooks/useAuth';
import ProjectApiService from '../api/ProjectApiService';
import { ReactComponent as EditIcon } from '../svg/Icon_Edit.svg';
import { ReactComponent as PlusIcon } from '../svg/PlusIcon.svg';
import ValidatedTextField from './parts/form/ValidatedTextField';

/** STYLES
* -most TextField and InputLabel styles are controlled by the theme
Expand Down Expand Up @@ -236,73 +235,16 @@ export default function ProjectForm({
})}
>
{arr.map((input) => (
<Box sx={{ mb: 1 }} key={input.name}>
<Grid container alignItems="center">
<Grid item xs="auto" sx={{ pr: 3 }}>
<InputLabel
sx={{ width: 'max-content', ml: 0.5, mb: 0.5 }}
id={input.name}
>
{input.label}
</InputLabel>
</Grid>
{input.name === 'location' && locationRadios}
</Grid>
{/* Sets text field and data (if needed) based on the whether it is as add or edit form page. */}
{isEdit ? (
/**
* Edit textfield.
* Includes
* - handleChange - to update the input fields based on users input.
* - value - formData that is passed from the DB to fill the input fields.
* */
<TextField
error={!!errors[input.name]}
type={input.type}
{...register(input.name, {
required: `${input.name} is required`,
pattern:
input.name === 'location'
? locationType === 'remote'
? {
value: input.value,
message: input.errorMessage,
}
: {
value: input.addressValue,
message: input.addressError,
}
: { value: input.value, message: input.errorMessage },
})}
placeholder={input.placeholder}
helperText={`${errors[input.name]?.message || ' '}`}
disabled={!editMode}
/>
) : (
// Add new project textfield.
<TextField
error={!!errors[input.name]}
type={input.type}
{...register(input.name, {
required: `${input.name} is required`,
pattern:
input.name === 'location'
? locationType === 'remote'
? {
value: input.value,
message: input.errorMessage,
}
: {
value: input.addressValue,
message: input.addressError,
}
: { value: input.value, message: input.errorMessage },
})}
placeholder={input.placeholder}
helperText={`${errors[input.name]?.message || ' '}`}
/>
)}
</Box>
<ValidatedTextField
key={input.name}
register={register}
isEdit={isEdit}
editMode={editMode}
locationType={locationType}
locationRadios={locationRadios}
errors={errors}
input={input}
/>
))}
</form>
<Box>
Expand Down
70 changes: 70 additions & 0 deletions client/src/components/parts/form/ValidatedTextField.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import { Box, Grid, InputLabel, TextField } from "@mui/material";

/**
* A validated text field component for forms.
*
* @component
* @param {Object} props - The component props.
* @param {Function} props.register - Function used for registering the input field with react-hook-form.
* @param {Object} props.errors - Object containing form validation errors.
* @param {boolean} props.isEdit - Boolean indicating if the form is in edit mode.
* @param {boolean} props.editMode - Boolean indicating if the component is in edit mode.
* @param {string} props.locationType - The type of location.
* @param {ReactNode} props.locationRadios - Radio Buttons for selecting location type.
* @param {Object} props.input - The input configuration for the text field.
* @returns {ReactElement} The rendered component.
*/
function ValidatedTextField({
register,
errors,
isEdit,
editMode,
locationType,
locationRadios,
input,
}) {
const registerObj = {
...register(input.name, {
required: `${input.name} is required`,
pattern:
input.name === 'location'
? locationType === 'remote'
? {
value: input.value,
message: input.errorMessage,
}
: {
value: input.addressValue,
message: input.addressError,
}
: { value: input.value, message: input.errorMessage },
}
)}

return (
<Box sx={{ mb: 1 }} key={input.name}>
<Grid container alignItems="center">
<Grid item xs="auto" sx={{ pr: 3 }}>
<InputLabel
sx={{ width: 'max-content', ml: 0.5, mb: 0.5 }}
id={input.name}
>
{input.label}
</InputLabel>
</Grid>
{input.name === 'location' && locationRadios}
</Grid>
<TextField
{...registerObj}
error={!!errors[input.name]}
type={input.type}
placeholder={input.placeholder}
helperText={`${errors[input.name]?.message || ' '}`}
disabled={isEdit ? !editMode : undefined} // handles edit mode for EditProjcet form
/>
</Box>
);
};

export default ValidatedTextField;

0 comments on commit c006b27

Please sign in to comment.