Fakultas Ilmu Komputer UI

index.tsx 3.79 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
41
42
  const [activeSlide, setActiveSlide] = useState(1);

  const {
    getTextInputProps,
    handleSubmit,
    isSubmitting,
    isFormUntouched,
    isFieldError,
  } = useForm({
43
44
45
    initialValues: dietReportCommentInitialValues,
    validationSchema: generateValidationSchema(fieldValidations),
    onSubmit: async (values) => {
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
      const payload: NutritionistCommentRequest = {
        weekly_report: userReports[userReports.length - 1].id,
        ...values,
      };
      const response = await createNutritionistCommentApi(payload);
      if (response.success && response.data) {
        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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
  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 => {
    if (activeSlide === 3) {
      return isFieldError('average_consumption');
    }
    const fields = [
      ...(dietReportTextFields[`dietReportPage${activeSlide}`] || []),
      ...(dietReportSelectFields[`dietReportPage${activeSlide}`] || []),
    ];
    return (
      isFormUntouched() ||
      fields.reduce(
        (acc: boolean, item) => acc || isFieldError(item.name),
        false,
      )
    );
  };

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