Skip to content

Commit

Permalink
Merge pull request #533 from codeforpdx/issue-442/basic-information-form
Browse files Browse the repository at this point in the history
Issue 442/basic information form
  • Loading branch information
andycwilliams authored Apr 24, 2024
2 parents 5590171 + fbb810b commit 4fa1dc6
Show file tree
Hide file tree
Showing 3 changed files with 257 additions and 8 deletions.
184 changes: 180 additions & 4 deletions src/components/CivicProfileForms/BasicInfo.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,184 @@
// React Imports
import React from 'react';
// MUI Imports
import Typography from '@mui/material/Typography';
import React, { useState, useEffect } from 'react';
// Material UI Imports
import Button from '@mui/material/Button';
import CheckIcon from '@mui/icons-material/Check';
import ClearIcon from '@mui/icons-material/Clear';
import FormControl from '@mui/material/FormControl';
import FormHelperText from '@mui/material/FormHelperText';
import Grid from '@mui/material/Grid';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import Select from '@mui/material/Select';
import TextField from '@mui/material/TextField';
import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import { LocalizationProvider } from '@mui/x-date-pickers/LocalizationProvider';
import dayjs from 'dayjs';
// Hook Imports
import { useCivicProfile, useNotification } from '@hooks';
// Component Imports
import { FormSection } from '../Form';

const BasicInfo = () => <Typography>Basic Info</Typography>;
/**
* BasicInfo Component - A form to fill out basic user info
*
* @memberof CivicProfileForms
* @name BasicInfo
* @returns {React.JSX.Element} The BasicInfo Component
*/
const BasicInfo = () => {
const { data, add, isSuccess, storedDataset, refetch } = useCivicProfile();
const { addNotification } = useNotification();
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
dateOfBirth: null,
gender: 9
});

useEffect(() => {
if (isSuccess) {
setFormData((prevFormData) => ({ ...prevFormData, ...data }));
}
}, [isSuccess, data]);
useEffect(() => {
if (!storedDataset) {
refetch();
}
}, [storedDataset]);
const handleChange = (e) => {
if (e.$isDayjsObject) {
setFormData((prevFormData) => ({
...prevFormData,
dateOfBirth: e.toDate()
}));
} else if (e.target) {
const { name, value } = e.target;
setFormData((prevFormData) => ({ ...prevFormData, [name]: value }));
}
};

const handleSubmit = (e) => {
e.preventDefault();
if (!isSuccess || !storedDataset) {
return;
}
add(formData);
addNotification('success', `Form submitted!`);
};

const handleClear = () => {
setFormData((prevFormData) => ({
...prevFormData,
firstName: '',
lastName: '',
dateOfBirth: null,
gender: 9
}));
addNotification('success', `Form cleared!`);
};

return (
<FormSection title="Basic Information">
<form aria-labelledby="add-contact-form" onSubmit={handleSubmit} autoComplete="off">
<Grid container spacing={2}>
<Grid item xs={12} md={6}>
<TextField
id="hmis-basic-info-first-name"
name="firstName"
label="Legal first name"
onChange={handleChange}
value={formData.firstName}
fullWidth
autoFocus
/>
</Grid>
<Grid item xs={12} md={6}>
<TextField
id="hmis-basic-info-last-name"
name="lastName"
label="Legal last name"
onChange={handleChange}
value={formData.lastName}
fullWidth
/>
</Grid>
<Grid item xs={12} md={6}>
<FormControl fullWidth>
<LocalizationProvider dateAdapter={AdapterDayjs}>
<DatePicker
id="hmis-basic-info-date-of-birth"
name="dateOfBirth"
label="Date of birth"
onChange={handleChange}
value={formData.dateOfBirth ? dayjs(formData.dateOfBirth) : null}
format="YYYY-MM-DD"
type="date"
disableFuture
openTo="year"
views={['year', 'month', 'day']}
/>
</LocalizationProvider>
<FormHelperText>YYYY-MM-DD</FormHelperText>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<FormControl fullWidth>
<InputLabel id="hmis-basic-info-gender">Gender</InputLabel>
<Select
id="hmis-basic-info-gender-select"
name="gender"
label="Gender"
onChange={handleChange}
value={formData.gender}
labelId="hmis-basic-info-gender"
defaultValue={9}
>
<MenuItem value={0}>Female</MenuItem>
<MenuItem value={1}>Male</MenuItem>
<MenuItem value={2}>Transgender male to female</MenuItem>
<MenuItem value={3}>Transgender female to male</MenuItem>
<MenuItem value={4}>Don&apos;t identify as male, female or transgender</MenuItem>
<MenuItem value={8}>Don&apos;t know</MenuItem>
<MenuItem value={9}>Decline to answer</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item xs={12} md={6}>
<Button
variant="outlined"
type="button"
label="Clear button"
color="error"
startIcon={<ClearIcon />}
fullWidth
sx={{ borderRadius: '20px' }}
onClick={handleClear}
aria-label="Clear button"
>
Clear
</Button>
</Grid>
<Grid item xs={12} md={6}>
<Button
variant="contained"
type="submit"
label="Submit button"
color="primary"
startIcon={<CheckIcon />}
fullWidth
sx={{ borderRadius: '20px' }}
disabled={!isSuccess}
aria-label="Submit button"
>
Submit
</Button>
</Grid>
</Grid>
</form>
</FormSection>
);
};

export default BasicInfo;
1 change: 1 addition & 0 deletions src/components/CivicProfileForms/HousingInfo.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const HousingInfo = () => {
const { name, value } = event.target;
setFormData((prevFormData) => ({ ...prevFormData, [name]: value }));
};

const handleSubmit = (e) => {
e.preventDefault();
if (!isSuccess || !storedDataset) {
Expand Down
80 changes: 76 additions & 4 deletions test/components/CivicProfileForms/BasicInfo.test.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,83 @@
import React from 'react';
import { render } from '@testing-library/react';
import { expect, it, describe } from 'vitest';
import { vi, expect, it, describe } from 'vitest';
import { BasicInfo } from '@components/CivicProfileForms';
import { useCivicProfile } from '@hooks';

describe('Basic Info Form', () => {
vi.mock('@hooks', async () => {
const actual = await vi.importActual('@hooks');

return {
...actual,
useCivicProfile: vi.fn()
};
});

describe('Basic info form', () => {
it('renders', () => {
const { getByText } = render(<BasicInfo />);
expect(getByText('Basic Info')).not.toBeNull();
useCivicProfile.mockReturnValue({ data: {}, isSuccess: true, refetch: vi.fn() });
const { getByRole } = render(<BasicInfo />);
const legalFirstName = getByRole('textbox', { name: 'Legal first name' });
expect(legalFirstName).not.toBeNull();
});

// TODO: Resolve test not passing
// it('clears all input fields when you click the clear button', async () => {
// const mockClear = vi.fn();
// const basicInfoProfile = {
// legalFirstName: 'Jane',
// legalLastName: 'Doe',
// legalDOB: '1980-12-15',
// legalGender: 1
// };
// useCivicProfile.mockReturnValue({
// add: mockClear,
// isSuccess: true,
// storedDataset: {},
// refetch: vi.fn()
// });
// const { getByRole } = render(<BasicInfo />);
// const legalFirstName = getByRole('textbox', { name: 'Legal first name' });
// const legalLastName = getByRole('textbox', { name: 'Legal last name' });
// const legalDOB = getByRole('textbox', { name: 'Choose date' });
// const legalGender = getByRole('combobox', { name: 'Gender' });
// const clearButton = getByRole('button', { name: 'Clear button' });

// await userEvent.type(legalFirstName, basicInfoProfile.legalFirstName);
// await userEvent.type(legalLastName, basicInfoProfile.legalLastName);
// await userEvent.type(legalDOB, basicInfoProfile.legalDOB);
// await userEvent.type(legalGender, `${basicInfoProfile.legalGender}{enter}`);

// await userEvent.click(clearButton);

// expect(legalFirstName.value).toBe('');
// expect(legalLastName.value).toBe('');
// expect(legalDOB.value).toBe(null);
// expect(legalGender.value).toBe('');
// });

// TODO: Resolve test not passing
// it('submits a basic info profile update when you click the submit button', async () => {
// const user = userEvent.setup();
// const mockAdd = vi.fn();
// const basicInfoProfile = {
// legalFirstName: 'Jane',
// legalLastName: 'Doe',
// legalDOB: '1980-12-15',
// legalGender: 1
// };
// useCivicProfile.mockReturnValue({ add: mockAdd, isSuccess: true });
// const { getByRole } = render(<BasicInfo />);
// const legalFirstName = getByRole('textbox', { name: 'Legal first name' });
// const legalLastName = getByRole('textbox', { name: 'Legal last name' });
// const legalDOB = getByRole('textbox', { name: 'Choose date' });
// const legalGender = getByRole('combobox', { name: 'Gender' });
// const submitButton = getByRole('button', { name: 'Submit button' });
// await user.type(legalFirstName, basicInfoProfile.legalFirstName);
// await user.type(legalLastName, basicInfoProfile.legalLastName);
// await user.type(legalDOB, basicInfoProfile.legalDOB);
// await user.type(legalGender, `${basicInfoProfile.legalGender}{enter}`);
// await user.click(submitButton);
// expect(mockAdd).toBeCalledWith(basicInfoProfile);
// });
});

0 comments on commit 4fa1dc6

Please sign in to comment.