Fakultas Ilmu Komputer UI

Commit 218014a4 authored by Wulan Mantiri's avatar Wulan Mantiri
Browse files

Merge branch 'PBI-17_chat_for_client' into 'staging'

Implement chat for client

See merge request !81
parents 54d0818b 608e3358
Pipeline #84067 passed with stages
in 68 minutes and 45 seconds
import { jest } from '@jest/globals';
import { iUserContext } from 'provider/UserContext/types';
export const mockUserContext: iUserContext = {
user: {
id: null,
email: '',
name: '',
role: null,
transaction_status: null,
is_finished_onboarding: false,
cart_id: null,
nutritionist: null,
},
isAuthenticated: false,
isLoading: false,
isFirstLoading: false,
setUser: jest.fn(),
getUser: jest.fn(),
signup: jest.fn(),
login: jest.fn(),
loginWithGoogle: jest.fn(),
logout: jest.fn(),
};
...@@ -30,6 +30,7 @@ export const initialUser = { ...@@ -30,6 +30,7 @@ export const initialUser = {
transaction_status: null, transaction_status: null,
is_finished_onboarding: false, is_finished_onboarding: false,
cart_id: null, cart_id: null,
nutritionist: null,
}; };
export const UserContext = createContext<iUserContext>({ export const UserContext = createContext<iUserContext>({
......
import React from 'react';
import { render, fireEvent } from '@testing-library/react-native';
import ChatForClient from '.';
import { UserContext } from 'provider/UserContext';
import { Linking } from 'react-native';
import { mockUserContext } from 'mocks/userContext';
describe('ChatForClient', () => {
it('call Linking open url when user clicks WhatsApp button and phone number exists', () => {
const userProviderValues = {
...mockUserContext,
user: {
...mockUserContext.user,
nutritionist: {
full_name_and_degree: 'tes',
phone_number: '09',
},
},
};
const { getByText } = render(
<UserContext.Provider value={userProviderValues}>
<ChatForClient />
</UserContext.Provider>,
);
const spy = jest.spyOn(Linking, 'openURL');
const wabutton = getByText('Hubungi via WhatsApp');
expect(wabutton).toBeTruthy();
fireEvent.press(wabutton);
expect(spy).toHaveBeenCalled();
spy.mockReset();
});
it('provides placeholder if nutritionist does not exist', () => {
const { getByText } = render(<ChatForClient />);
const placeholder = getByText(
/Anda tidak didaftarkan dengan sebuah nutrisionis/i,
);
expect(placeholder).toBeTruthy();
});
});
import React, { FC, useContext } from 'react';
import { View, Text } from 'react-native';
import { Button } from 'react-native-elements';
import { UserContext } from 'provider';
import { redirectToWA } from 'utils/chat';
import { styles } from './styles';
import { EmptyDataPage } from 'components/core';
const ChatForClient: FC = () => {
const { user } = useContext(UserContext);
return (
<View style={styles.container}>
{user.nutritionist ? (
<View>
<Text style={styles.nutritionist}>Nutrisionis Anda:</Text>
<Text style={styles.name}>
👩🏻‍⚕️ {user.nutritionist.full_name_and_degree}
</Text>
<Button
title="Hubungi via WhatsApp"
icon={{
name: 'whatsapp',
type: 'material-community',
color: 'white',
size: 28,
}}
onPress={() => redirectToWA(user.nutritionist?.phone_number)}
buttonStyle={styles.buttonStyle}
titleStyle={styles.titleStyle}
/>
</View>
) : (
<EmptyDataPage text="Anda tidak didaftarkan dengan sebuah nutrisionis." />
)}
</View>
);
};
export default ChatForClient;
import { StyleSheet } from 'react-native';
import { colors, typography } from 'styles';
export const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
},
nutritionist: {
textAlign: 'center',
...typography.headingMedium,
color: colors.formLabel,
marginBottom: 16,
},
name: {
textAlign: 'center',
...typography.headingLarge,
color: colors.textBlack,
marginBottom: 40,
},
buttonStyle: {
backgroundColor: colors.primaryVariant,
},
titleStyle: {
color: 'white',
...typography.headingMedium,
marginLeft: 10,
},
});
...@@ -9,7 +9,6 @@ import { styles, tabBarOptions } from './styles'; ...@@ -9,7 +9,6 @@ import { styles, tabBarOptions } from './styles';
import ClientRecommendation from 'scenes/recommendation/ClientRecommendation'; import ClientRecommendation from 'scenes/recommendation/ClientRecommendation';
import WeeklyReport from 'scenes/report/WeeklyReport'; import WeeklyReport from 'scenes/report/WeeklyReport';
import ComingSoonPage from 'scenes/common/ComingSoonPage';
import ExtendedQuestionnaire from 'scenes/questionnaire/ExtendedQuestionnaire'; import ExtendedQuestionnaire from 'scenes/questionnaire/ExtendedQuestionnaire';
import { import {
ConsentForm, ConsentForm,
...@@ -21,6 +20,8 @@ import { ...@@ -21,6 +20,8 @@ import {
} from 'scenes/questionnaire/ExtendedQuestionnaire/components'; } from 'scenes/questionnaire/ExtendedQuestionnaire/components';
import ReadOnlyWeeklyReport from 'scenes/report/ReadOnlyWeeklyReport'; import ReadOnlyWeeklyReport from 'scenes/report/ReadOnlyWeeklyReport';
import ChooseWeekForClient from 'scenes/report/ChooseWeekForClient'; import ChooseWeekForClient from 'scenes/report/ChooseWeekForClient';
//import ComingSoonPage from 'scenes/common/ComingSoonPage';
import ChatForClient from 'scenes/chat/ChatForClient';
interface NavRoute<T = any> { interface NavRoute<T = any> {
name: string; name: string;
...@@ -154,7 +155,7 @@ const ClientNavigation: FC = () => { ...@@ -154,7 +155,7 @@ const ClientNavigation: FC = () => {
/> />
<ClientTab.Screen <ClientTab.Screen
name={ROUTES.clientChat} name={ROUTES.clientChat}
component={ComingSoonPage} component={ChatForClient}
options={{ options={{
tabBarLabel: 'Chat', tabBarLabel: 'Chat',
tabBarIcon: ({ color, size }) => ( tabBarIcon: ({ color, size }) => (
......
...@@ -29,6 +29,10 @@ export interface AuthUserResponse extends User { ...@@ -29,6 +29,10 @@ export interface AuthUserResponse extends User {
transaction_status: TransactionStatus | null; transaction_status: TransactionStatus | null;
is_finished_onboarding: boolean; is_finished_onboarding: boolean;
cart_id: number | null; cart_id: number | null;
nutritionist: {
full_name_and_degree: string;
phone_number: string | null;
} | null;
} }
export interface LoginRequest { export interface LoginRequest {
......
import { Linking } from 'react-native';
import { cleanPhoneNumber } from './format';
import Toast from 'react-native-toast-message';
export const redirectToWA = (phoneNumber?: string | null) => {
if (phoneNumber) {
const url = 'https://wa.me/' + cleanPhoneNumber(phoneNumber);
Linking.openURL(url);
} else {
Toast.show({
type: 'error',
text1: 'Nomor WhatsApp tidak diketahui.',
text2:
'Orang yang dituju tidak memiliki nomor WhatsApp. Mohon hubungi CS kami jika terdapat kesalahan.',
});
}
};
...@@ -22,3 +22,9 @@ export const getDateRange = ( ...@@ -22,3 +22,9 @@ export const getDateRange = (
sun: dayjs().day(7).subtract(weekDiff, 'week'), sun: dayjs().day(7).subtract(weekDiff, 'week'),
}; };
}; };
export const cleanPhoneNumber = (phoneNumber: string) => {
const num =
phoneNumber[0] === '0' ? phoneNumber.replace(/0/, '62') : phoneNumber;
return num.replace(/\+|-/g, '');
};
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