Fakultas Ilmu Komputer UI

index.tsx 3.92 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, Loader, EmptyDataPage, Toast } 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
11
import { useRoute, useNavigation } from '@react-navigation/native';
import {
12
  retrieveUserReportByIdApi,
13
14
15
16
17
18
19
20
21
22
23
24
  createNutritionistCommentApi,
} from 'services/progress';
import { NutritionistCommentRequest } from 'services/progress/models';
import * as ROUTES from 'constants/routes';
import {
  dietReportTextFields,
  dietReportSelectFields,
} from 'constants/weeklyReport';

interface ParamsDietReport {
  id: number;
}
25
26

const DietReportForNutritionist: FC = () => {
27
28
29
30
  const navigation = useNavigation();
  const route = useRoute();
  const { id } = route.params as ParamsDietReport;
  const { isLoading, data: userReports = [] } = useApi(() =>
31
    retrieveUserReportByIdApi(id),
32
  );
33

34
35
36
37
38
39
40
  const [activeSlide, setActiveSlide] = useState(1);

  const {
    getTextInputProps,
    handleSubmit,
    isSubmitting,
    isFieldError,
41
    values: formValues,
42
  } = useForm({
43
44
45
    initialValues: dietReportCommentInitialValues,
    validationSchema: generateValidationSchema(fieldValidations),
    onSubmit: async (values) => {
46
47
48
49
50
      const payload: NutritionistCommentRequest = {
        weekly_report: userReports[userReports.length - 1].id,
        ...values,
      };
      const response = await createNutritionistCommentApi(payload);
51
      if (response.success) {
52
53
54
55
56
57
58
59
60
61
62
63
64
        Toast.show({
          type: 'success',
          text1: 'Sukses membuat komen',
          text2: 'Komen anda terhadap laporan mingguan klien sudah tersimpan.',
        });
        navigation.navigate(ROUTES.clientListForNutritionist);
      } else {
        Toast.show({
          type: 'error',
          text1: 'Gagal membuat komen',
          text2: 'Komen anda terhadap laporan mingguan klien gagal tersimpan.',
        });
      }
65
66
67
    },
  });

68
69
70
71
72
73
74
75
76
77
78
  if (isLoading) {
    return <Loader />;
  }

  if (!userReports.length) {
    return <EmptyDataPage text="Klien belum mengisi laporan diet mingguan" />;
  }

  const userReport = userReports[userReports.length - 1];

  const isCurrentPageError = (): boolean => {
79
80
81
82
83
84
85
    if (activeSlide === 1) {
      return [
        formValues.height,
        formValues.weight,
        formValues.waist_size,
      ].reduce((acc: boolean, item) => acc || item === '', false);
    }
86
87
88
89
    if (activeSlide === 3) {
      return isFieldError('average_consumption');
    }
    const fields = [
90
91
      ...dietReportTextFields[`dietReportPage${activeSlide}`],
      ...dietReportSelectFields[`dietReportPage${activeSlide}`],
92
    ];
93
94
95
    return fields.reduce(
      (acc: boolean, item) => acc || isFieldError(item.name),
      false,
96
97
98
    );
  };

99
100
  return (
    <View style={[layoutStyles, styles.reportContainer]}>
101
102
103
104
105
106
107
108
109
110
111
112
113
114
      <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}
          />
        ))}
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
      />
    </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;