Fakultas Ilmu Komputer UI
Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
ppl-fasilkom-ui
2021
Kelas D
PT Gizi Sehat - Dietela
Dietela Mobile
Commits
aa14a6d3
Commit
aa14a6d3
authored
Jun 24, 2021
by
Kefas Satrio Bangkit Solideantyo
Browse files
[REFACTOR] integrate choose weekly report page with backend
parent
bbff4370
Pipeline
#83128
failed with stages
in 8 minutes and 15 seconds
Changes
17
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/constants/navigation.ts
View file @
aa14a6d3
...
...
@@ -23,6 +23,7 @@ import {
ClientListAdmin
,
LoginChoosePlan
,
ClientNavigation
,
ChooseWeekForNutritionist
,
}
from
'
scenes
'
;
import
{
FC
}
from
'
react
'
;
import
DietReportForNutritionist
from
'
scenes/nutritionist/DietReportForNutritionist
'
;
...
...
@@ -119,7 +120,7 @@ export const paidClientNavigation: NavRoute[] = [
header
:
'
Dietela
'
,
},
];
// ChooseWeekForNutritionist
export
const
nutritionistNavigation
:
NavRoute
[]
=
[
{
name
:
ROUTES
.
clientListForNutritionist
,
...
...
@@ -131,6 +132,11 @@ export const nutritionistNavigation: NavRoute[] = [
component
:
ComingSoonPage
,
header
:
'
Chat Klien
'
,
},
{
name
:
ROUTES
.
weeklyReportChooseWeekForNutritionist
,
component
:
ChooseWeekForNutritionist
,
header
:
'
Daftar Laporan Klien
'
,
},
{
name
:
ROUTES
.
clientDietReportNutritionist
,
component
:
DietReportForNutritionist
,
...
...
src/constants/routes.ts
View file @
aa14a6d3
...
...
@@ -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`
;
src/mocks/userReport.ts
View file @
aa14a6d3
...
...
@@ -42,11 +42,10 @@ export const mockUserReportResponse: UserReportResponse = {
...
mockUserReportRequest
,
};
// TODO: to be adjusted
export
const
mockUserReportHistory
=
{
has_
not_filled_form
:
tru
e
,
current
_week
_num
:
14
,
reports
:
[
has_
submitted_this_week
:
fals
e
,
today
_week
:
14
,
data
:
[
{
...
mockUserReportResponse
,
week_num
:
12
,
...
...
src/scenes/nutritionist/ClientListNutritionist/index.tsx
View file @
aa14a6d3
...
...
@@ -8,7 +8,7 @@ const ClientListNutritionist: FC = () => {
<
ClientList
role
=
{
UserRole
.
NUTRITIONIST
}
clientProfileRoute
=
{
ROUTES
.
clientProfileNutritionist
}
clientDietReportRoute
=
{
ROUTES
.
clientDietReport
Nutritionist
}
clientDietReportRoute
=
{
ROUTES
.
weeklyReportChooseWeekFor
Nutritionist
}
clientChatRoute
=
{
ROUTES
.
clientChatNutritionist
}
/>
);
...
...
src/scenes/nutritionist/DietReportForNutritionist/index.test.tsx
View file @
aa14a6d3
...
...
@@ -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
();
});
...
...
src/scenes/nutritionist/DietReportForNutritionist/index.tsx
View file @
aa14a6d3
...
...
@@ -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
)
{
...
...
src/scenes/report/ChooseWeek/index.test.tsx
View file @
aa14a6d3
...
...
@@ -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
:
fals
e
}
}
data
=
{
{
...
mockUserReportHistory
,
has_
submitted_this_week
:
tru
e
}
}
/>,
);
expect
(
queryByText
(
/Isi/i
)).
toBeFalsy
();
...
...
src/scenes/report/ChooseWeek/index.tsx
View file @
aa14a6d3
...
...
@@ -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
}
/>
...
...
src/scenes/report/ChooseWeek/types.ts
View file @
aa14a6d3
import
{
UserReportResponse
}
from
'
services/progress/models
'
;
import
{
UserReport
s
Response
}
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
;
}
src/scenes/report/ChooseWeekForClient/index.test.tsx
View file @
aa14a6d3
import
React
from
'
react
'
;
import
{
render
}
from
'
@testing-library/react-native
'
;
import
{
render
}
from
'
utils/testing
'
;
import
*
as
ROUTES
from
'
constants/routes
'
;
import
ChooseWeekForClient
from
'
.
'
;
const
mockedNavigate
=
jest
.
fn
();
jest
.
mock
(
'
@react-navigation/native
'
,
()
=>
{
return
{
useNavigation
:
()
=>
({
navigate
:
mockedNavigate
,
}),
};
});
describe
(
'
ChooseWeekForClient
'
,
()
=>
{
it
(
'
renders correctly
'
,
()
=>
{
render
(<
ChooseWeekForClient
/>);
render
(<
ChooseWeekForClient
/>
,
ROUTES
.
weeklyReportChooseWeek
);
});
});
src/scenes/report/ChooseWeekForClient/index.tsx
View file @
aa14a6d3
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
}
/>;
};
...
...
src/scenes/report/ChooseWeekForNutritionist/index.test.tsx
View file @
aa14a6d3
import
React
from
'
react
'
;
import
{
render
}
from
'
@testing-library/react-native
'
;
import
{
render
}
from
'
utils/testing
'
;
import
*
as
ROUTES
from
'
constants/routes
'
;
import
ChooseWeekForNutritionist
from
'
.
'
;
const
mockedNavigate
=
jest
.
fn
();
jest
.
mock
(
'
@react-navigation/native
'
,
()
=>
{
return
{
useNavigation
:
()
=>
({
navigate
:
mockedNavigate
,
}),
};
});
describe
(
'
ChooseWeekForNutritionist
'
,
()
=>
{
it
(
'
renders correctly
'
,
()
=>
{
render
(<
ChooseWeekForNutritionist
/>);
render
(
<
ChooseWeekForNutritionist
/>,
ROUTES
.
weeklyReportChooseWeekForNutritionist
,
{
routeParams
:
{
id
:
1
,
},
},
);
});
});
src/scenes/report/ChooseWeekForNutritionist/index.tsx
View file @
aa14a6d3
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
/>;
};
...
...
src/scenes/report/ReadOnlyWeeklyReport/index.tsx
View file @
aa14a6d3
...
...
@@ -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
)
{
...
...
src/services/progress/index.ts
View file @
aa14a6d3
...
...
@@ -6,11 +6,12 @@ import {
UserReportRequest
,
NutritionistCommentRequest
,
NutritionistCommentResponse
,
UserReportsResponse
,
}
from
'
./models
'
;
export
const
retrieveUserReportByIdApi
=
(
clientId
:
number
,
):
ApiResponse
<
UserReportResponse
[]
>
=>
{
export
const
retrieveUserReport
s
ByIdApi
=
(
clientId
:
number
|
null
,
):
ApiResponse
<
UserReport
s
Response
>
=>
{
return
api
(
RequestMethod
.
GET
,
apiUrls
.
userReportByClientId
(
clientId
));
};
...
...
src/services/progress/models.ts
View file @
aa14a6d3
...
...
@@ -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
;
...
...
src/services/progress/urls.ts
View file @
aa14a6d3
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
}
`
;
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment