Fakultas Ilmu Komputer UI

integrate choose weekly report page with backend

parent bbff4370
......@@ -23,6 +23,7 @@ import {
ClientListAdmin,
LoginChoosePlan,
ClientNavigation,
ChooseWeekForNutritionist,
} from 'scenes';
import { FC } from 'react';
import DietReportForNutritionist from 'scenes/nutritionist/DietReportForNutritionist';
......@@ -131,6 +132,11 @@ export const nutritionistNavigation: NavRoute[] = [
component: ComingSoonPage,
header: 'Chat Klien',
},
{
name: ROUTES.weeklyReportChooseWeekForNutritionist,
component: ChooseWeekForNutritionist,
header: 'Riwayat Laporan Diet Klien',
},
{
name: ROUTES.clientDietReportNutritionist,
component: DietReportForNutritionist,
......
......@@ -47,4 +47,5 @@ export const clientDietRecommendation = `${admin}/client-diet-recommendation`;
const weeklyReport = 'weekly-report';
export const weeklyReportForm = `${weeklyReport}/form`;
export const weeklyReportChooseWeek = `${weeklyReport}/choose-week`;
export const weeklyReportChooseWeekForNutritionist = `${weeklyReport}/choose-week-for-nutritionist`;
export const weeklyReportReadOnly = `${weeklyReport}/read-only`;
......@@ -42,11 +42,10 @@ export const mockUserReportResponse: UserReportResponse = {
...mockUserReportRequest,
};
// TODO: to be adjusted
export const mockUserReportHistory = {
has_not_filled_form: true,
current_week_num: 14,
reports: [
has_submitted_this_week: false,
today_week: 14,
data: [
{
...mockUserReportResponse,
week_num: 12,
......
......@@ -8,7 +8,7 @@ const ClientListNutritionist: FC = () => {
<ClientList
role={UserRole.NUTRITIONIST}
clientProfileRoute={ROUTES.clientProfileNutritionist}
clientDietReportRoute={ROUTES.clientDietReportNutritionist}
clientDietReportRoute={ROUTES.weeklyReportChooseWeekForNutritionist}
clientChatRoute={ROUTES.clientChatNutritionist}
/>
);
......
......@@ -11,23 +11,16 @@ jest.mock('axios');
const mockAxios = axios as jest.Mocked<typeof axios>;
describe('DietReportForNutritionist', () => {
const userReports = [mockUserReportResponse];
const data = mockUserReportResponse;
it('renders and submits correctly when given valid comments', async () => {
mockAxios.request.mockImplementationOnce(() =>
Promise.resolve({
status: 200,
data: userReports,
}),
);
const { queryByText, getByText, getAllByPlaceholderText } = render(
<DietReportForNutritionist />,
ROUTES.clientDietReportNutritionist,
{
routeParams: { id: 1 },
routeParams: data,
},
);
await waitFor(() => expect(mockAxios.request).toBeCalled());
const textFieldsPage1 = getAllByPlaceholderText(/Tuliskan komentar.../i);
textFieldsPage1.forEach((field) => {
......@@ -68,20 +61,13 @@ describe('DietReportForNutritionist', () => {
});
it('renders and does not redirect when api fails', async () => {
mockAxios.request.mockImplementationOnce(() =>
Promise.resolve({
status: 200,
data: userReports,
}),
);
const { queryByText, getByText, getAllByPlaceholderText } = render(
<DietReportForNutritionist />,
ROUTES.clientDietReportNutritionist,
{
routeParams: { id: 1 },
routeParams: data,
},
);
await waitFor(() => expect(mockAxios.request).toBeCalled());
const textFieldsPage1 = getAllByPlaceholderText(/Tuliskan komentar.../i);
textFieldsPage1.forEach((field) => {
......@@ -123,28 +109,6 @@ describe('DietReportForNutritionist', () => {
expect(queryByText(/Daftar Klien/i)).toBeFalsy();
});
it('shows empty data page when no data', async () => {
mockAxios.request.mockImplementationOnce(() =>
Promise.resolve({
status: 200,
data: [],
}),
);
const { queryByText } = render(
<DietReportForNutritionist />,
ROUTES.clientDietReportNutritionist,
{
routeParams: { id: 0 },
},
);
await waitFor(() => expect(mockAxios.request).toBeCalled());
expect(
queryByText(/Klien belum mengisi laporan diet mingguan/i),
).toBeTruthy();
});
afterAll(() => {
jest.clearAllMocks();
});
......
......@@ -2,17 +2,17 @@ import React, { FC, useState } from 'react';
import { View, StyleSheet } from 'react-native';
import { layoutStyles } from 'styles';
import { pages } from './pages';
import { WizardContainer, Loader, EmptyDataPage, Toast } from 'components/core';
import { useForm, useApi } from 'hooks';
import { WizardContainer, Toast } from 'components/core';
import { useForm } from 'hooks';
import { dietReportCommentInitialValues, fieldValidations } from './schema';
import { generateValidationSchema } from 'utils/form';
import { DietReportPage } from './components';
import { useRoute, useNavigation } from '@react-navigation/native';
import { createNutritionistCommentApi } from 'services/progress';
import {
retrieveUserReportByIdApi,
createNutritionistCommentApi,
} from 'services/progress';
import { NutritionistCommentRequest } from 'services/progress/models';
NutritionistCommentRequest,
UserReportResponse,
} from 'services/progress/models';
import * as ROUTES from 'constants/routes';
import {
dietReportTextFields,
......@@ -26,10 +26,7 @@ interface ParamsDietReport {
const DietReportForNutritionist: FC = () => {
const navigation = useNavigation();
const route = useRoute();
const { id } = route.params as ParamsDietReport;
const { isLoading, data: userReports = [] } = useApi(() =>
retrieveUserReportByIdApi(id),
);
const data = route.params as UserReportResponse;
const [activeSlide, setActiveSlide] = useState(1);
......@@ -44,7 +41,7 @@ const DietReportForNutritionist: FC = () => {
validationSchema: generateValidationSchema(fieldValidations),
onSubmit: async (values) => {
const payload: NutritionistCommentRequest = {
weekly_report: userReports[userReports.length - 1].id,
weekly_report: data.id,
...values,
};
const response = await createNutritionistCommentApi(payload);
......@@ -65,15 +62,7 @@ const DietReportForNutritionist: FC = () => {
},
});
if (isLoading) {
return <Loader />;
}
if (!userReports.length) {
return <EmptyDataPage text="Klien belum mengisi laporan diet mingguan" />;
}
const userReport = userReports[userReports.length - 1];
const userReport = data;
const isCurrentPageError = (): boolean => {
if (activeSlide === 1) {
......
......@@ -34,7 +34,7 @@ describe('ChooseWeek component', () => {
it('does not have "Isi" button when form is already filled', () => {
const { queryByText } = render(
<ChooseWeek
data={{ ...mockUserReportHistory, has_not_filled_form: false }}
data={{ ...mockUserReportHistory, has_submitted_this_week: true }}
/>,
);
expect(queryByText(/Isi/i)).toBeFalsy();
......
......@@ -7,24 +7,31 @@ import * as ROUTES from 'constants/routes';
import { styles } from './styles';
import { Props } from './types';
import { getDateRange } from 'utils/format';
import { EmptyDataPage } from 'components/core';
const ChooseWeek: FC<Props> = ({ data, isNutritionist }) => {
const redirectViewRoute = isNutritionist ? '' : ROUTES.weeklyReportReadOnly; // TODO
const redirectViewRoute = isNutritionist
? ROUTES.clientDietReportNutritionist
: ROUTES.weeklyReportReadOnly;
const navigation = useNavigation();
if (!data) {
return <EmptyDataPage text="Laporan mingguan tidak ditemukan" />;
}
const getDateRangeForWeek = (weekNum: number) => {
const { mon, sun } = getDateRange(data.current_week_num - weekNum);
const { mon, sun } = getDateRange(data.today_week - weekNum);
return `${mon.format('DD MMM YYYY')} - ${sun.format('DD MMM YYYY')}`;
};
return (
<ScrollView contentContainerStyle={styles.container}>
<View style={styles.pageContainer}>
{!isNutritionist && data.has_not_filled_form ? (
{!isNutritionist && !data.has_submitted_this_week ? (
<View style={styles.page}>
<View style={styles.text}>
<Text style={styles.bold}>Minggu {data.current_week_num}</Text>
<Text>{getDateRangeForWeek(data.current_week_num)}</Text>
<Text style={styles.bold}>Minggu {data.today_week}</Text>
<Text>{getDateRangeForWeek(data.today_week)}</Text>
</View>
<View style={styles.buttonContainer}>
<Button
......@@ -36,7 +43,7 @@ const ChooseWeek: FC<Props> = ({ data, isNutritionist }) => {
</View>
</View>
) : null}
{data.reports.map((report, i) => (
{data.data.map((report, i) => (
<View style={styles.page} key={i}>
<View style={styles.text}>
<Text style={styles.bold}>Minggu {report.week_num}</Text>
......@@ -46,7 +53,7 @@ const ChooseWeek: FC<Props> = ({ data, isNutritionist }) => {
<Button
title="Lihat"
type="outline"
onPress={() => navigation.navigate(redirectViewRoute)}
onPress={() => navigation.navigate(redirectViewRoute, report)}
buttonStyle={styles.outlineButtonStyle}
titleStyle={styles.buttonTitle}
/>
......
import { UserReportResponse } from 'services/progress/models';
import { UserReportsResponse } from 'services/progress/models';
export interface Props {
data: {
has_not_filled_form: boolean;
current_week_num: number;
reports: UserReportResponse[];
}; // TODO: Kefas adjust to API response
data: UserReportsResponse | undefined;
isNutritionist?: boolean;
}
import React, { FC } from 'react';
import React, { FC, useContext } from 'react';
import ChooseWeek from '../ChooseWeek';
import { mockUserReportHistory } from 'mocks/userReport';
import { Loader } from 'components/core';
import { retrieveUserReportsByIdApi } from 'services/progress';
import { useApi } from 'hooks';
import { UserContext } from 'provider';
const ChooseWeekForClient: FC = () => {
// call for API, get client id from user context? or discuss with backend
const data = mockUserReportHistory;
const { user } = useContext(UserContext);
const { isLoading, data } = useApi(() => retrieveUserReportsByIdApi(user.id));
if (isLoading) {
return <Loader />;
}
return <ChooseWeek data={data} />;
};
......
......@@ -10,6 +10,11 @@ jest.mock('@react-navigation/native', () => {
useNavigation: () => ({
navigate: mockedNavigate,
}),
useRoute: () => ({
params: {
id: 1,
},
}),
};
});
......
import React, { FC } from 'react';
import ChooseWeek from '../ChooseWeek';
import { mockUserReportHistory } from 'mocks/userReport';
import { useApi } from 'hooks';
import { retrieveUserReportsByIdApi } from 'services/progress';
import { Loader } from 'components/core';
import { useRoute } from '@react-navigation/native';
const ChooseWeekForNutritionist: FC = () => {
// call for API, get client id dr yg d pass?
const data = mockUserReportHistory;
const route = useRoute();
const { id } = route.params as { id: number };
const { isLoading, data } = useApi(() => retrieveUserReportsByIdApi(id));
if (isLoading) {
return <Loader />;
}
return <ChooseWeek data={data} isNutritionist />;
};
......
......@@ -15,19 +15,19 @@ import { page4 } from './pages/Page4';
const ReadOnlyWeeklyReport: FC = () => {
const [activeSlide, setActiveSlide] = useState(0);
const route = useRoute();
const data = route.params as UserReportResponse[];
const data = route.params as UserReportResponse;
const { isLoading, data: commentData } = useApi(() =>
retrieveUserReportCommentByReportId(data[0].id),
retrieveUserReportCommentByReportId(data.id),
);
const pageComponents = [
<WeeklyReportPage questions={page1(data[0])} title="Laporan Diet Anda" />,
<WeeklyReportPage questions={page2(data[0])} />,
<WeeklyReportPage questions={page1(data)} title="Laporan Diet Anda" />,
<WeeklyReportPage questions={page2(data)} />,
<WeeklyReportPage
questions={page3(data[0])}
questions={page3(data)}
title="Selama 1 minggu terakhir, berapa rata-rata Anda mengonsumsi jenis makanan dibawah ini selama seharian?"
/>,
<WeeklyReportPage questions={page4(data[0])} />,
<WeeklyReportPage questions={page4(data)} />,
];
if (isLoading) {
......
......@@ -6,11 +6,12 @@ import {
UserReportRequest,
NutritionistCommentRequest,
NutritionistCommentResponse,
UserReportsResponse,
} from './models';
export const retrieveUserReportByIdApi = (
clientId: number,
): ApiResponse<UserReportResponse[]> => {
export const retrieveUserReportsByIdApi = (
clientId: number | null,
): ApiResponse<UserReportsResponse> => {
return api(RequestMethod.GET, apiUrls.userReportByClientId(clientId));
};
......
......@@ -32,6 +32,12 @@ export interface UserReportResponse extends UserReportRequest {
week_num: number;
}
export interface UserReportsResponse {
has_submitted_this_week: boolean;
today_week: number;
data: UserReportResponse[];
}
export interface NutritionistComment {
weight: string;
height: string;
......
export const progress = 'progress/';
export const userReport = `${progress}user_report/`;
export const userReportByClientId = (id: number) =>
export const userReportByClientId = (id: number | null) =>
`${userReport}?client_id=${id}`;
export const userReportCommentByReportId = (id: number) =>
`${progress}nutritionist_comment/?weekly_report_id=${id}`;
......
Markdown is supported
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