Fakultas Ilmu Komputer UI

index.tsx 4.68 KB
Newer Older
1
import React, { FC, useState } from 'react';
2
import { View, StyleSheet } from 'react-native';
3
4
import { layoutStyles } from 'styles';
import { pages } from './pages';
5
6
import { WizardContainer, Toast, Loader } from 'components/core';
import { useForm, useApi } from 'hooks';
7
8
9
import { dietReportCommentInitialValues, fieldValidations } from './schema';
import { generateValidationSchema } from 'utils/form';
import { DietReportPage } from './components';
10
import { useRoute, useNavigation } from '@react-navigation/native';
11
12
13
14
15
import {
  createNutritionistCommentApi,
  retrieveUserReportCommentByReportId,
  updateNutritionistCommentApi,
} from 'services/progress';
16
import {
17
18
  NutritionistCommentRequest,
  UserReportResponse,
19
  NutritionistComment,
20
} from 'services/progress/models';
21
22
23
24
25
26
import * as ROUTES from 'constants/routes';
import {
  dietReportTextFields,
  dietReportSelectFields,
} from 'constants/weeklyReport';

27
const DietReportForNutritionist: FC = () => {
28
29
  const navigation = useNavigation();
  const route = useRoute();
30
  const userReport = route.params as UserReportResponse;
31

32
33
  const [activeSlide, setActiveSlide] = useState(1);

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  const { isLoading, data: commentResponse } = useApi(() =>
    retrieveUserReportCommentByReportId(userReport.id),
  );

  const getInitialValues = () => {
    let defaultValues = { ...dietReportCommentInitialValues };
    if (commentResponse && commentResponse.length > 0) {
      const data = commentResponse[0];
      Object.entries(data).map(([field, comment]) => {
        const key = field as keyof NutritionistComment;
        defaultValues[key] = comment;
      });
    }
    return defaultValues;
  };

50
51
52
53
54
  const {
    getTextInputProps,
    handleSubmit,
    isSubmitting,
    isFieldError,
55
    values: formValues,
56
  } = useForm({
57
    initialValues: getInitialValues(),
58
    validationSchema: generateValidationSchema(fieldValidations),
59
    enableReinitialize: true,
60
    onSubmit: async (values) => {
61
      const payload: NutritionistCommentRequest = {
62
        weekly_report: userReport.id,
63
64
        ...values,
      };
65
66
67
68
69
70
71
72
      const commentId =
        commentResponse && commentResponse.length > 0
          ? commentResponse[0].id
          : null;
      const response = commentId
        ? await updateNutritionistCommentApi(payload, commentId)
        : await createNutritionistCommentApi(payload);

73
      if (response.success) {
74
75
76
77
78
79
80
81
82
83
84
85
86
87
        commentId
          ? Toast.show({
              type: 'success',
              text1: 'Sukses mengubah komen',
              text2:
                'Perubahan komen Anda terhadap laporan mingguan klien sudah tersimpan.',
            })
          : Toast.show({
              type: 'success',
              text1: 'Sukses membuat komen',
              text2:
                'Komen Anda terhadap laporan mingguan klien sudah tersimpan.',
            });
        navigation.navigate(ROUTES.weeklyReportChooseWeekForNutritionist);
88
89
90
91
92
93
94
      } else {
        Toast.show({
          type: 'error',
          text1: 'Gagal membuat komen',
          text2: 'Komen anda terhadap laporan mingguan klien gagal tersimpan.',
        });
      }
95
96
97
    },
  });

98
99
100
  if (isLoading) {
    return <Loader />;
  }
101
102

  const isCurrentPageError = (): boolean => {
103
104
105
106
107
108
109
    if (activeSlide === 1) {
      return [
        formValues.height,
        formValues.weight,
        formValues.waist_size,
      ].reduce((acc: boolean, item) => acc || item === '', false);
    }
110
111
112
113
    if (activeSlide === 3) {
      return isFieldError('average_consumption');
    }
    const fields = [
114
115
      ...dietReportTextFields[`dietReportPage${activeSlide}`],
      ...dietReportSelectFields[`dietReportPage${activeSlide}`],
116
    ];
117
118
119
    return fields.reduce(
      (acc: boolean, item) => acc || isFieldError(item.name),
      false,
120
121
122
    );
  };

123
124
  return (
    <View style={[layoutStyles, styles.reportContainer]}>
125
126
127
128
129
130
131
132
133
134
135
136
137
138
      <WizardContainer
        currentStep={activeSlide}
        setCurrentStep={setActiveSlide}
        onFinish={handleSubmit}
        isLoading={isSubmitting}
        isNextDisabled={isCurrentPageError()}
        components={pages.map((page, idx) => (
          <DietReportPage
            key={idx}
            content={page.pageContent(userReport, getTextInputProps)}
            pageName={page.pageName}
            getTextInputProps={getTextInputProps}
          />
        ))}
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
      />
    </View>
  );
};

const styles = StyleSheet.create({
  flexContainer: {
    flex: 1,
  },
  reportContainer: {
    position: 'relative',
    flex: 1,
    paddingBottom: 20,
  },
  searchContainer: {
    backgroundColor: 'white',
    borderWidth: 1,
    borderRadius: 5,
    marginBottom: 20,
    justifyContent: 'center',
    height: 58,
  },
  backgroundWhite: { backgroundColor: 'white' },
});

export default DietReportForNutritionist;