Fakultas Ilmu Komputer UI

Commit 7c265074 authored by Wulan Mantiri's avatar Wulan Mantiri
Browse files

Merge branch 'PBI-9-diet_questionnaire_ui_and_validation' into 'staging'

Implement diet questionnaire UI layout and form validation

See merge request !41
parents 012d6878 0be41e76
Pipeline #75934 passed with stages
in 84 minutes and 46 seconds
import React, { FC } from 'react';
import { View } from 'react-native';
import { TextField, CheckboxGroup } from 'components/form';
import { textFields, selectFields } from 'constants/questionnaire';
import { initialValues } from './schema';
import QuestionnaireWrapper, { styles } from '../QuestionnaireWrapper';
const Questionnaire5: FC = () => (
<QuestionnaireWrapper
Questionnaire={({ getTextInputProps, getFormFieldProps }) => (
<View>
{selectFields.healthCondition.map((props, i) => (
<View key={`checkbox${i}`} style={styles.spacing}>
<CheckboxGroup
{...props}
choices={props.choiceList.map((label, id) => ({
label,
value: id + 1,
}))}
{...getFormFieldProps(props.name)}
/>
</View>
))}
{textFields.healthCondition.map((props, i) => (
<TextField
{...props}
{...getTextInputProps(props.name)}
multiline
key={`textfield${i}`}
/>
))}
</View>
)}
initialValues={initialValues}
/>
);
export default Questionnaire5;
export const initialValues = {
disease: [],
complaint: [],
regular_drug_consumption: '',
other_disease: '',
motivation_using_dietela: '',
dietela_nutritionist_expectation: '',
dietela_program_expectation: '',
};
import React, { FC } from 'react';
import { ScrollView, StyleSheet } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import { BigButton } from 'components/core';
import * as ROUTES from 'constants/routes';
import { useForm } from 'hooks';
import { layoutStyles } from 'styles';
import { generateValidationSchema } from 'utils/form';
import { Props } from './types';
const QuestionnaireWrapper: FC<Props> = ({
Questionnaire,
initialValues,
fieldValidations = [],
}) => {
const navigation = useNavigation();
const {
getTextInputProps,
getFormFieldProps,
handleSubmit,
isSubmitting,
} = useForm({
initialValues,
validationSchema: generateValidationSchema(fieldValidations),
onSubmit: async (values) => {
console.log(values);
navigation.navigate(ROUTES.extendedQuestionnaire);
},
});
return (
<ScrollView contentContainerStyle={layoutStyles}>
<Questionnaire
getTextInputProps={getTextInputProps}
getFormFieldProps={getFormFieldProps}
/>
<BigButton title="lanjut" onPress={handleSubmit} loading={isSubmitting} />
</ScrollView>
);
};
export const styles = StyleSheet.create({
spacing: {
marginBottom: 24,
},
});
export default QuestionnaireWrapper;
import { FC } from 'react';
import { FieldValidation } from 'utils/form';
export interface QuestionnaireProps {
getTextInputProps: (_: string) => any;
getFormFieldProps: (_: string) => any;
}
export interface Props {
Questionnaire: FC<QuestionnaireProps>;
initialValues: { [_: string]: any };
fieldValidations?: FieldValidation[];
}
export { default as ConsentForm } from './ConsentForm';
export { default as Questionnaire1 } from './Questionnaire1';
export { default as Questionnaire2 } from './Questionnaire2';
export { default as Questionnaire3 } from './Questionnaire3';
export { default as Questionnaire4 } from './Questionnaire4';
export { default as Questionnaire5 } from './Questionnaire5';
......@@ -2,20 +2,19 @@ import React, { FC, useState } from 'react';
import * as ROUTES from 'constants/routes';
import { StepByStepForm } from 'components/form';
import { pages } from './schema';
import { pageHeaders } from 'constants/questionnaire';
const ExtendedQuestionnaire: FC = () => {
const [currentPage] = useState(1);
const [currentPage] = useState(6);
return (
<StepByStepForm
currentPage={currentPage}
title={'Lengkapi Profil Anda'}
pages={pages.map((name, i) => ({
pages={pageHeaders.map((name, i) => ({
name,
route: ROUTES.extendedQuestionnaireById(i),
}))}
finishRedirectRoute={ROUTES.profile}
finishRedirectRoute={ROUTES.clientProfile}
/>
);
};
......
export const pages: string[] = [
'Identitas Diri',
'Pola Makan',
'Konsumsi Makanan Seharian',
'Gaya Hidup dan Kebiasaan Diet',
'Kondisi Pribadi',
];
import { DietProfileResponse } from 'services/dietelaQuiz/models';
import { CartResponse } from 'services/payment/models';
import { CartResponse, TransactionStatus } from 'services/payment/models';
export interface GoogleLoginRequest {
access_token: string;
......@@ -23,6 +23,8 @@ export interface User {
email: string;
name: string;
role: UserRole | null;
transaction_status: TransactionStatus;
has_profile: boolean;
}
export interface LoginRequest {
......
......@@ -26,10 +26,8 @@ export const theme: Theme = {
padding: 14,
},
textStyle: {
fontWeight: '500',
color: 'black',
...typography.bodyLarge,
paddingRight: 14,
fontWeight: '400',
...typography.bodyMedium,
},
size: 18,
checkedColor: colors.primary,
......@@ -39,12 +37,6 @@ export const theme: Theme = {
containerStyle: {
paddingHorizontal: 0,
},
inputContainerStyle: {
borderColor: colors.border,
borderWidth: 1,
borderRadius: 4,
paddingHorizontal: 10,
},
inputStyle: {
...typography.bodyMedium,
},
......
import * as Yup from 'yup';
import { ReactNode } from 'react';
export enum FieldType {
TEXT = 'text',
......@@ -12,7 +13,8 @@ export enum FieldType {
export interface FieldValidation {
name: string;
required?: boolean;
label?: string;
label?: ReactNode;
errorMessage?: string;
type: FieldType;
matches?: string;
}
......@@ -25,7 +27,7 @@ export const generateValidationSchema = (fields: FieldValidation[]) => {
case FieldType.TEXT:
tempYup = Yup.string();
validationSchema[field.name] = field.required
? tempYup.required(`${field.label} harus diisi`)
? tempYup.required(`${field.errorMessage || field.label} harus diisi`)
: tempYup;
break;
case FieldType.EMAIL:
......
import dayjs, { Dayjs } from 'dayjs';
export const convertDate = (dateString?: string): string => {
return dateString ? dayjs(dateString).format('D MMM YYYY') : '';
};
export const dateToString = (date: Dayjs): string => date.format('YYYY-MM-DD');
......@@ -1109,6 +1109,13 @@
sudo-prompt "^9.0.0"
wcwidth "^1.0.1"
"@react-native-community/datetimepicker@^3.4.7":
version "3.4.7"
resolved "https://registry.yarnpkg.com/@react-native-community/datetimepicker/-/datetimepicker-3.4.7.tgz#84613cda2cf06315530628cdf07c77076eae5ec3"
integrity sha512-T5MG05ekf9iLSdpBPDbXcOUP6c9pNVhCEVCp9jfjQxj+4dpVQMiCSyLJdPM543uv9KloIZZ71vs+Um01AbwO7A==
dependencies:
invariant "^2.2.4"
"@react-native-community/eslint-config@^1.1.0":
version "1.1.0"
resolved "https://registry.npmjs.org/@react-native-community/eslint-config/-/eslint-config-1.1.0.tgz"
......@@ -1143,6 +1150,11 @@
resolved "https://registry.yarnpkg.com/@react-native-google-signin/google-signin/-/google-signin-6.0.0.tgz#115b666221169cbd6aabd6d9a622a7f48205ea2e"
integrity sha512-xmrrG2muhwmoPy9AdfP+ceLBZtnrXkZwgN/jR5u3xOHadyerJfvD76w2BSmm7zeoiMB1wwSkZkzFSa9+i1BdKA==
"@react-native-picker/picker@^1.15.0":
version "1.15.0"
resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-1.15.0.tgz#f571a8b013e001a840db905b21ec18e9d205f01b"
integrity sha512-TYdhavldt3ami860fVgYv2mf0d1u5YhMQ6kTw+soX/a1rYbpRCRjdz01sEQXwCW8oL7/lzHakOFnwqCo6JazDw==
"@react-navigation/core@^5.15.2":
version "5.15.2"
resolved "https://registry.npmjs.org/@react-navigation/core/-/core-5.15.2.tgz"
......@@ -2506,6 +2518,11 @@ data-urls@^1.1.0:
whatwg-mimetype "^2.2.0"
whatwg-url "^7.0.0"
dayjs@^1.10.4:
version "1.10.4"
resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.4.tgz#8e544a9b8683f61783f570980a8a80eaf54ab1e2"
integrity sha512-RI/Hh4kqRc1UKLOAf/T5zdMMX5DQIlDxwUe3wSyMMnEbGunnpENCdbUgM+dW7kXidZqCttBrmw7BhN4TMddkCw==
dayjs@^1.8.15:
version "1.10.4"
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.10.4.tgz"
......
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