Fakultas Ilmu Komputer UI

Commit 3d046098 authored by Wulan Mantiri's avatar Wulan Mantiri
Browse files

Merge branch 'add-form-validation' into 'staging'

[REFACTOR] Adjust form validation for questionnaire and weekly report

See merge request !78
parents c0589f58 e9003249
Pipeline #82980 passed with stages
in 46 minutes and 30 seconds
import { yesOrNo, drinkFrequency, physicalActivity } from 'constants/options'; import { yesOrNo, drinkFrequency, physicalActivity } from 'constants/options';
import { TextFieldSchema } from 'types/form'; import { TextFieldSchema, SelectFieldSchema } from 'types/form';
import { FieldType } from 'utils/form';
export const pageHeaders: string[] = [ export const pageHeaders: string[] = [
'Persetujuan Program Diet', 'Persetujuan Program Diet',
...@@ -41,6 +42,8 @@ export const textFields: { [_: string]: TextFieldSchema[] } = { ...@@ -41,6 +42,8 @@ export const textFields: { [_: string]: TextFieldSchema[] } = {
placeholder: 'Ex: 100', placeholder: 'Ex: 100',
name: 'waist_size', name: 'waist_size',
required: true, required: true,
fieldType: FieldType.NUMBER,
max: 150,
keyboardType: 'numeric', keyboardType: 'numeric',
}, },
], ],
...@@ -163,7 +166,7 @@ export const textFields: { [_: string]: TextFieldSchema[] } = { ...@@ -163,7 +166,7 @@ export const textFields: { [_: string]: TextFieldSchema[] } = {
], ],
}; };
export const selectFields: { [_: string]: any[] } = { export const selectFields: { [_: string]: SelectFieldSchema[] } = {
identity: [ identity: [
{ {
name: 'profession', name: 'profession',
......
...@@ -5,6 +5,7 @@ import { ...@@ -5,6 +5,7 @@ import {
likertScale5, likertScale5,
physicalActivity, physicalActivity,
} from './options'; } from './options';
import { FieldType } from 'utils/form';
export const dietReportTextFields: { [_: string]: TextFieldSchema[] } = { export const dietReportTextFields: { [_: string]: TextFieldSchema[] } = {
dietReportPage1: [ dietReportPage1: [
...@@ -13,6 +14,7 @@ export const dietReportTextFields: { [_: string]: TextFieldSchema[] } = { ...@@ -13,6 +14,7 @@ export const dietReportTextFields: { [_: string]: TextFieldSchema[] } = {
placeholder: 'Masukkan berat badan yang terakhir diukur', placeholder: 'Masukkan berat badan yang terakhir diukur',
name: 'weight', name: 'weight',
required: true, required: true,
fieldType: FieldType.NUMBER,
keyboardType: 'numeric', keyboardType: 'numeric',
}, },
{ {
...@@ -20,6 +22,7 @@ export const dietReportTextFields: { [_: string]: TextFieldSchema[] } = { ...@@ -20,6 +22,7 @@ export const dietReportTextFields: { [_: string]: TextFieldSchema[] } = {
placeholder: 'Masukkan tinggi badan yang terakhir diukur', placeholder: 'Masukkan tinggi badan yang terakhir diukur',
name: 'height', name: 'height',
required: true, required: true,
fieldType: FieldType.NUMBER,
keyboardType: 'numeric', keyboardType: 'numeric',
}, },
{ {
...@@ -27,6 +30,8 @@ export const dietReportTextFields: { [_: string]: TextFieldSchema[] } = { ...@@ -27,6 +30,8 @@ export const dietReportTextFields: { [_: string]: TextFieldSchema[] } = {
placeholder: 'Masukkan lingkar pinggang yang terakhir diukur', placeholder: 'Masukkan lingkar pinggang yang terakhir diukur',
name: 'waist_size', name: 'waist_size',
required: true, required: true,
fieldType: FieldType.NUMBER,
max: 150,
keyboardType: 'numeric', keyboardType: 'numeric',
}, },
], ],
......
...@@ -13,6 +13,7 @@ export const textFields: TextFieldSchema[] = [ ...@@ -13,6 +13,7 @@ export const textFields: TextFieldSchema[] = [
label: 'Email', label: 'Email',
placeholder: 'example@address.com', placeholder: 'example@address.com',
required: true, required: true,
fieldType: FieldType.EMAIL,
name: 'email', name: 'email',
}, },
{ {
...@@ -20,6 +21,8 @@ export const textFields: TextFieldSchema[] = [ ...@@ -20,6 +21,8 @@ export const textFields: TextFieldSchema[] = [
placeholder: 'Ex: 20', placeholder: 'Ex: 20',
required: true, required: true,
name: 'age', name: 'age',
fieldType: FieldType.NUMBER,
max: 80,
keyboardType: 'numeric', keyboardType: 'numeric',
}, },
{ {
...@@ -27,12 +30,14 @@ export const textFields: TextFieldSchema[] = [ ...@@ -27,12 +30,14 @@ export const textFields: TextFieldSchema[] = [
placeholder: 'Ex: 60', placeholder: 'Ex: 60',
required: true, required: true,
name: 'weight', name: 'weight',
fieldType: FieldType.NUMBER,
keyboardType: 'numeric', keyboardType: 'numeric',
}, },
{ {
label: 'Tinggi badan (cm)', label: 'Tinggi badan (cm)',
placeholder: 'Ex: 160', placeholder: 'Ex: 160',
required: true, required: true,
fieldType: FieldType.NUMBER,
name: 'height', name: 'height',
keyboardType: 'numeric', keyboardType: 'numeric',
}, },
...@@ -265,7 +270,8 @@ export const fieldValidations: FieldValidation[] = [ ...@@ -265,7 +270,8 @@ export const fieldValidations: FieldValidation[] = [
name: field.name, name: field.name,
required: field.required, required: field.required,
label: field.label, label: field.label,
type: field.name === 'email' ? FieldType.EMAIL : FieldType.TEXT, type: field.fieldType || FieldType.TEXT,
max: field.max,
})), })),
...radioButtonGroups.map((field) => ({ ...radioButtonGroups.map((field) => ({
name: field.name, name: field.name,
......
...@@ -8,7 +8,7 @@ import { ...@@ -8,7 +8,7 @@ import {
} from 'components/form'; } from 'components/form';
import { initialValues, fieldValidations, convertPayload } from './schema'; import { initialValues, fieldValidations, convertPayload } from './schema';
import { textFields, selectFields } from 'constants/questionnaire'; import { textFields, selectFields, dateField } from 'constants/questionnaire';
import QuestionnaireWrapper, { styles } from '../QuestionnaireWrapper'; import QuestionnaireWrapper, { styles } from '../QuestionnaireWrapper';
import { NavProps } from '../QuestionnaireWrapper/types'; import { NavProps } from '../QuestionnaireWrapper/types';
...@@ -18,8 +18,8 @@ const Questionnaire1: FC<NavProps> = (navProps) => ( ...@@ -18,8 +18,8 @@ const Questionnaire1: FC<NavProps> = (navProps) => (
Questionnaire={({ getTextInputProps, getFormFieldProps }) => ( Questionnaire={({ getTextInputProps, getFormFieldProps }) => (
<View> <View>
<Datepicker <Datepicker
{...getFormFieldProps('date_of_birth')} {...getFormFieldProps(dateField.name)}
label="Tanggal Lahir" label={dateField.label}
required required
/> />
{textFields.identity.map((props, i) => ( {textFields.identity.map((props, i) => (
......
...@@ -22,7 +22,8 @@ export const fieldValidations: FieldValidation[] = [ ...@@ -22,7 +22,8 @@ export const fieldValidations: FieldValidation[] = [
name: field.name, name: field.name,
required: field.required, required: field.required,
label: field.label, label: field.label,
type: FieldType.TEXT, type: field.fieldType || FieldType.TEXT,
max: field.max,
})), })),
...selectFields.identity.map((field) => ({ ...selectFields.identity.map((field) => ({
name: field.name, name: field.name,
......
...@@ -27,7 +27,7 @@ describe('WeeklyReport', () => { ...@@ -27,7 +27,7 @@ describe('WeeklyReport', () => {
const validFormValues: { [_: string]: any } = { const validFormValues: { [_: string]: any } = {
weight: '52', weight: '52',
height: '90', height: '90',
waist_size: '190', waist_size: '100',
changes_felt: 1, changes_felt: 1,
hunger_level: 1, hunger_level: 1,
fullness_level: 1, fullness_level: 1,
......
...@@ -38,7 +38,8 @@ export const fieldValidations: FieldValidation[] = [ ...@@ -38,7 +38,8 @@ export const fieldValidations: FieldValidation[] = [
required: field.required, required: field.required,
label: field.label, label: field.label,
errorMessage: field.errorMessage, errorMessage: field.errorMessage,
type: FieldType.TEXT, type: field.fieldType || FieldType.TEXT,
max: field.max,
})), })),
...Object.values(dietReportSelectFields) ...Object.values(dietReportSelectFields)
.reduce((acc, arr) => [...acc, ...arr], []) .reduce((acc, arr) => [...acc, ...arr], [])
......
import { Props as TextFieldProps } from 'components/form/TextField/types'; import { Props as TextFieldProps } from 'components/form/TextField/types';
import { Props as FormLabelProps } from 'components/form/FormLabel/types'; import { Props as FormLabelProps } from 'components/form/FormLabel/types';
import { Choice } from 'components/form/MultipleChoice/types'; import { Choice } from 'components/form/MultipleChoice/types';
import { FieldType } from 'utils/form';
export type TextFieldSchema = TextFieldProps & { export type TextFieldSchema = TextFieldProps & {
name: string; name: string;
fieldType?: FieldType;
max?: number;
}; };
export interface RadioButtonGroupSchema extends FormLabelProps { export interface RadioButtonGroupSchema extends FormLabelProps {
choices: Choice[]; choices: Choice[];
name: string; name: string;
} }
export interface SelectFieldSchema extends FormLabelProps {
name: string;
picker?: boolean;
placeholder?: string;
hasOtherChoice?: boolean;
otherChoiceValue?: number;
choiceList: string[];
}
...@@ -8,6 +8,7 @@ export enum FieldType { ...@@ -8,6 +8,7 @@ export enum FieldType {
CHECKBOX = 'checkbox', CHECKBOX = 'checkbox',
PASSWORD = 'password', PASSWORD = 'password',
CONFIRM_PASSWORD = 'confirmpassword', CONFIRM_PASSWORD = 'confirmpassword',
NUMBER = 'number',
} }
export interface FieldValidation { export interface FieldValidation {
...@@ -16,6 +17,8 @@ export interface FieldValidation { ...@@ -16,6 +17,8 @@ export interface FieldValidation {
label?: ReactNode; label?: ReactNode;
errorMessage?: string; errorMessage?: string;
type: FieldType; type: FieldType;
min?: number;
max?: number;
matches?: string; matches?: string;
} }
...@@ -58,6 +61,14 @@ export const generateValidationSchema = (fields: FieldValidation[]) => { ...@@ -58,6 +61,14 @@ export const generateValidationSchema = (fields: FieldValidation[]) => {
'Konfirmasi password tidak sama', 'Konfirmasi password tidak sama',
); );
break; break;
case FieldType.NUMBER:
validationSchema[field.name] = Yup.number()
.min(field.min || 0, `${field.label} harus minimal ${field.min || 0}`)
.max(
field.max || 200,
`${field.label} harus maksimal ${field.max || 200}`,
);
break;
default: default:
break; break;
} }
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment