From d2eb577305b02ad48c916cca412d84e5065393ff Mon Sep 17 00:00:00 2001 From: Vishal Date: Wed, 2 Aug 2023 16:20:38 +0530 Subject: [PATCH 01/13] Adds dynamic contact history --- graphql/queries/Contact.ts | 14 ++++++++++ screens/ContactHistory.tsx | 54 +++++++++++++++++++++++++++++++++++--- 2 files changed, 65 insertions(+), 3 deletions(-) diff --git a/graphql/queries/Contact.ts b/graphql/queries/Contact.ts index 1ddef39..31a11fc 100644 --- a/graphql/queries/Contact.ts +++ b/graphql/queries/Contact.ts @@ -17,3 +17,17 @@ export const GET_CONTACTS = gql` } } `; + +export const GET_CONTACT_HISTORY = gql` + query ContactHistory($filter: ContactsHistoryFilter, $opts: Opts) { + contactHistory(filter: $filter, opts: $opts) { + eventDatetime + eventLabel + eventMeta + eventType + id + insertedAt + updatedAt + } + } +`; diff --git a/screens/ContactHistory.tsx b/screens/ContactHistory.tsx index a3c0d77..d435687 100644 --- a/screens/ContactHistory.tsx +++ b/screens/ContactHistory.tsx @@ -1,8 +1,16 @@ -import React from 'react'; +import React, { useState } from 'react'; import { FlatList, Pressable, StyleSheet, Text, View } from 'react-native'; import moment from 'moment'; import { COLORS, SIZES } from '../constants'; import { Feather } from '@expo/vector-icons'; +import { useQuery } from '@apollo/client'; +import { GET_CONTACT_HISTORY } from '../graphql/queries/Contact'; + +type History = { + id: string; + date: string; + action: string; +}; const data = [ { @@ -32,12 +40,52 @@ const formatDate = (date: string) => { return moment(givenDate).format('DD/MM/YYYY, HH:mm:ss'); }; -const ContactHistory = () => { +const formatHistory = (histories): History[] => { + return histories.map((history) => { + return { + id: history.id, + date: moment.utc(history.eventDatetime).valueOf(), + action: history.eventLabel, + }; + }); +}; +interface Props { + navigation: unknown; + route: { + params: { + id: string; + }; + }; +} + +const ContactHistory = ({ navigation, route }: Props) => { + const contactId = route.params; + const [historyData, setHistoryData] = useState([]); + const { loading } = useQuery(GET_CONTACT_HISTORY, { + variables: { + opts: { + order: 'ASC', + limit: 10, + offset: 0, + }, + filter: { + contactId: contactId, + }, + }, + onCompleted: (data) => { + const formattedHistory = formatHistory(data.contactHistory); + setHistoryData(formattedHistory); + }, + onError: (error) => { + console.log(error.message); + }, + }); + return ( <> ( {item.action} From 635bd7e1eb08d17b419761681ed270472fdea342 Mon Sep 17 00:00:00 2001 From: Vishal Date: Thu, 3 Aug 2023 15:21:04 +0530 Subject: [PATCH 02/13] Implements Dynamic History --- graphql/queries/Contact.ts | 6 ++++ screens/ContactHistory.tsx | 58 ++++++++++++++++++-------------------- screens/ContactProfile.tsx | 2 +- 3 files changed, 35 insertions(+), 31 deletions(-) diff --git a/graphql/queries/Contact.ts b/graphql/queries/Contact.ts index 31a11fc..3e54f6a 100644 --- a/graphql/queries/Contact.ts +++ b/graphql/queries/Contact.ts @@ -31,3 +31,9 @@ export const GET_CONTACT_HISTORY = gql` } } `; + +export const COUNT_CONTACT_HISTORY = gql` + query countContactHistory($filter: ContactsHistoryFilter) { + countContactHistory(filter: $filter) + } +`; diff --git a/screens/ContactHistory.tsx b/screens/ContactHistory.tsx index d435687..6a90712 100644 --- a/screens/ContactHistory.tsx +++ b/screens/ContactHistory.tsx @@ -4,7 +4,8 @@ import moment from 'moment'; import { COLORS, SIZES } from '../constants'; import { Feather } from '@expo/vector-icons'; import { useQuery } from '@apollo/client'; -import { GET_CONTACT_HISTORY } from '../graphql/queries/Contact'; +import { COUNT_CONTACT_HISTORY, GET_CONTACT_HISTORY } from '../graphql/queries/Contact'; +import Loading from '../components/ui/Loading'; type History = { id: string; @@ -12,29 +13,6 @@ type History = { action: string; }; -const data = [ - { - id: '1', - date: '2023-07-19T03:22:11.442Z', - action: 'Flow Started: Registration Workflow', - }, - { - id: '2', - date: '2023-07-19T03:22:11.442Z', - action: 'Added to collection: "Optin contacts"', - }, - { - id: '3', - date: '2023-07-19T03:22:11.442Z', - action: 'Changed contact language to English', - }, - { - id: '4', - date: '2023-07-19T03:22:11.442Z', - action: 'Flow Started: Optin Workflow', - }, -]; - const formatDate = (date: string) => { const givenDate = new Date(date); return moment(givenDate).format('DD/MM/YYYY, HH:mm:ss'); @@ -42,10 +20,14 @@ const formatDate = (date: string) => { const formatHistory = (histories): History[] => { return histories.map((history) => { + let flow = ''; + if (history.eventLabel === 'Flow Started') { + flow = JSON.parse(history.eventMeta).flow.name; + } return { id: history.id, date: moment.utc(history.eventDatetime).valueOf(), - action: history.eventLabel, + action: `${history.eventLabel}${flow ? `: ${flow}` : ''}`, }; }); }; @@ -61,11 +43,24 @@ interface Props { const ContactHistory = ({ navigation, route }: Props) => { const contactId = route.params; const [historyData, setHistoryData] = useState([]); + const [numHistory, setNumHistory] = useState(10); + const [totalHistoryCount, setTotalHistoryCount] = useState(0); + + useQuery(COUNT_CONTACT_HISTORY, { + variables: { + filter: { + contactId: contactId, + }, + }, + onCompleted: (data) => { + setTotalHistoryCount(data.countContactHistory); + }, + }); const { loading } = useQuery(GET_CONTACT_HISTORY, { variables: { opts: { order: 'ASC', - limit: 10, + limit: numHistory, offset: 0, }, filter: { @@ -93,10 +88,13 @@ const ContactHistory = ({ navigation, route }: Props) => { )} /> - console.log('Load more')} style={styles.loadMoreButton}> - Load More - - + {numHistory < totalHistoryCount ? ( + setNumHistory(numHistory + 10)} style={styles.loadMoreButton}> + Load More + + + ) : null} + {loading && } ); }; diff --git a/screens/ContactProfile.tsx b/screens/ContactProfile.tsx index b71ea22..fac5e04 100644 --- a/screens/ContactProfile.tsx +++ b/screens/ContactProfile.tsx @@ -66,7 +66,7 @@ const ContactProfile = ({ navigation, route }: Props) => { navigation.navigate('ContactHistory')} + onPress={() => navigation.navigate('ContactHistory', contact.id)} android_ripple={{ color: COLORS.black005 }} > Contact History From df2c6cc416eedb36eaeb97212ba21308e38a9fd3 Mon Sep 17 00:00:00 2001 From: Vishal Date: Fri, 4 Aug 2023 03:16:56 +0530 Subject: [PATCH 03/13] Makes the Info Page dynamic --- graphql/queries/Contact.ts | 23 +++++++++++ screens/ContactInfo.tsx | 30 ++++++++++---- screens/ContactProfile.tsx | 83 ++++++++++++++++++++++++++++++++++---- 3 files changed, 120 insertions(+), 16 deletions(-) diff --git a/graphql/queries/Contact.ts b/graphql/queries/Contact.ts index 3e54f6a..c52d39b 100644 --- a/graphql/queries/Contact.ts +++ b/graphql/queries/Contact.ts @@ -37,3 +37,26 @@ export const COUNT_CONTACT_HISTORY = gql` countContactHistory(filter: $filter) } `; + +export const GET_CONTACT_INFO = gql` + query contact($id: ID!) { + contact(id: $id) { + contact { + id + name + phone + status + language { + label + } + fields + groups { + label + users { + name + } + } + } + } + } +`; diff --git a/screens/ContactInfo.tsx b/screens/ContactInfo.tsx index d1e03ce..a29f028 100644 --- a/screens/ContactInfo.tsx +++ b/screens/ContactInfo.tsx @@ -1,19 +1,28 @@ import React from 'react'; -import { StyleSheet, View, ScrollView } from 'react-native'; +import { StyleSheet, View, ScrollView, Text } from 'react-native'; import FieldValue from '../components/ui/FieldValue'; import { COLORS, SIZES } from '../constants'; -const ContactInfo = () => { +interface Props { + navigation: unknown; + route: { + params: { + object: { [key: string]: string }; + }; + }; +} +const ContactInfo = ({ navigation, route }: Props) => { return ( - - - - - - + {Object.keys(route.params).length === 0 ? ( + No Fields Available + ) : ( + Object.entries(route.params).map(([field, value]) => ( + + )) + )} ); @@ -33,4 +42,9 @@ const styles = StyleSheet.create({ backgroundColor: COLORS.white, flex: 1, }, + placeholder: { + color: COLORS.darkGray, + fontSize: SIZES.f14, + textAlign: 'center', + }, }); diff --git a/screens/ContactProfile.tsx b/screens/ContactProfile.tsx index fac5e04..42ddebc 100644 --- a/screens/ContactProfile.tsx +++ b/screens/ContactProfile.tsx @@ -1,8 +1,11 @@ -import React from 'react'; +import React, { useState } from 'react'; import { View, Text, StyleSheet, Pressable, ScrollView } from 'react-native'; import { AntDesign } from '@expo/vector-icons'; import { COLORS, SCALE, SIZES } from '../constants'; import FieldValue from '../components/ui/FieldValue'; +import { useQuery } from '@apollo/client'; +import { GET_CONTACT_INFO } from '../graphql/queries/Contact'; +import { getSessionTimeLeft } from '../utils/helper'; interface Props { navigation: unknown; @@ -16,10 +19,57 @@ interface Props { }; }; } +interface ContactInfoProp { + name: string; + phone: string; + status: string; + language: string; + assignedTo: string[]; + collections: string[]; + fields: { [key: string]: string }; +} + +const formatInfo = (contacts): ContactInfoProp => { + const { contact } = contacts; + const assignedTo = []; + const collections = []; + + for (const group of contact.groups) { + collections.push(group.label); + for (const user of group.users) { + assignedTo.push(user.name); + } + } + const fields = JSON.parse(contact.fields); + const fieldInfo: { [key: string]: string } = {}; + for (const key in fields) { + const item = fields[key]; + fieldInfo[item.label] = item.value; + } + return { + name: contact.name, + phone: contact.phone, + status: contact.status, + language: contact.language.label, + assignedTo, + collections, + fields: fieldInfo, + }; +}; const ContactProfile = ({ navigation, route }: Props) => { const { contact } = route.params; + const [contactInfo, setContactInfo] = useState([]); + const { loading } = useQuery(GET_CONTACT_INFO, { + variables: { + id: contact.id, + }, + onCompleted: (data) => { + const formattedInfo = formatInfo(data.contact); + setContactInfo(formattedInfo); + }, + }); return ( @@ -31,7 +81,7 @@ const ContactProfile = ({ navigation, route }: Props) => { onPress={(): void => navigation.goBack()} /> - Session Timer: 0 + Session Timer: {getSessionTimeLeft(contact.lastMessageAt)}hrs @@ -46,20 +96,37 @@ const ContactProfile = ({ navigation, route }: Props) => { - - + + 0 + ? contactInfo.assignedTo.join(', ') + : 'None' + } + /> - - + + - + 0 + ? contactInfo.collections.join(', ') + : 'None' + } + /> navigation.navigate('ContactInformation')} + onPress={() => navigation.navigate('ContactInformation', contactInfo.fields)} android_ripple={{ color: COLORS.black005 }} > View Info From c1f4c858514512178fa0b1858de762b6fd1a25a6 Mon Sep 17 00:00:00 2001 From: Vishal Date: Sat, 5 Aug 2023 10:20:38 +0530 Subject: [PATCH 04/13] Loads more history on scroll --- graphql/queries/Contact.ts | 6 -- screens/ContactHistory.tsx | 130 +++++++++++++++++++------------------ 2 files changed, 66 insertions(+), 70 deletions(-) diff --git a/graphql/queries/Contact.ts b/graphql/queries/Contact.ts index c52d39b..fdf40e6 100644 --- a/graphql/queries/Contact.ts +++ b/graphql/queries/Contact.ts @@ -32,12 +32,6 @@ export const GET_CONTACT_HISTORY = gql` } `; -export const COUNT_CONTACT_HISTORY = gql` - query countContactHistory($filter: ContactsHistoryFilter) { - countContactHistory(filter: $filter) - } -`; - export const GET_CONTACT_INFO = gql` query contact($id: ID!) { contact(id: $id) { diff --git a/screens/ContactHistory.tsx b/screens/ContactHistory.tsx index 6a90712..f5c966d 100644 --- a/screens/ContactHistory.tsx +++ b/screens/ContactHistory.tsx @@ -1,10 +1,9 @@ import React, { useState } from 'react'; -import { FlatList, Pressable, StyleSheet, Text, View } from 'react-native'; +import { FlatList, StyleSheet, Text, View } from 'react-native'; import moment from 'moment'; import { COLORS, SIZES } from '../constants'; -import { Feather } from '@expo/vector-icons'; import { useQuery } from '@apollo/client'; -import { COUNT_CONTACT_HISTORY, GET_CONTACT_HISTORY } from '../graphql/queries/Contact'; +import { GET_CONTACT_HISTORY } from '../graphql/queries/Contact'; import Loading from '../components/ui/Loading'; type History = { @@ -32,7 +31,6 @@ const formatHistory = (histories): History[] => { }); }; interface Props { - navigation: unknown; route: { params: { id: string; @@ -40,33 +38,25 @@ interface Props { }; } -const ContactHistory = ({ navigation, route }: Props) => { - const contactId = route.params; +const ContactHistory = ({ route }: Props) => { + const { id: contactId } = route.params; const [historyData, setHistoryData] = useState([]); - const [numHistory, setNumHistory] = useState(10); - const [totalHistoryCount, setTotalHistoryCount] = useState(0); - - useQuery(COUNT_CONTACT_HISTORY, { - variables: { - filter: { - contactId: contactId, - }, + const [noMoreItems, setNoMoreItems] = useState(false); + const [pageNo, setPageNo] = useState(1); + const historyVariables = { + opts: { + order: 'ASC', + limit: 10, + offset: 0, }, - onCompleted: (data) => { - setTotalHistoryCount(data.countContactHistory); - }, - }); - const { loading } = useQuery(GET_CONTACT_HISTORY, { - variables: { - opts: { - order: 'ASC', - limit: numHistory, - offset: 0, - }, - filter: { - contactId: contactId, - }, + filter: { + contactId: contactId, }, + }; + + const { loading, fetchMore } = useQuery(GET_CONTACT_HISTORY, { + variables: historyVariables, + fetchPolicy: 'network-only', onCompleted: (data) => { const formattedHistory = formatHistory(data.contactHistory); setHistoryData(formattedHistory); @@ -76,24 +66,49 @@ const ContactHistory = ({ navigation, route }: Props) => { }, }); + const handleLoadMore = () => { + if (loading || noMoreItems) return; + fetchMore({ + variables: { + ...historyVariables, + opts: { + ...historyVariables.opts, + offset: pageNo * 10 + 1, + }, + }, + updateQuery: (prev, { fetchMoreResult }) => { + if (!fetchMoreResult || fetchMoreResult.contactHistory.length === 0) { + // If there are no more items, set noMoreItems to true + setNoMoreItems(true); + return prev; + } + if (fetchMoreResult.contactHistory.length < 10) setNoMoreItems(true); + setPageNo(pageNo + 1); + // Append new data to the existing data + return { contactHistory: [...prev.contactHistory, ...fetchMoreResult.contactHistory] }; + }, + }); + }; + return ( <> - ( - - {item.action} - {formatDate(item.date)} - - )} - /> - {numHistory < totalHistoryCount ? ( - setNumHistory(numHistory + 10)} style={styles.loadMoreButton}> - Load More - - - ) : null} + {historyData.length > 0 ? ( + ( + + {item.action} + {formatDate(item.date)} + + )} + onEndReached={handleLoadMore} + onEndReachedThreshold={0.1} + /> + ) : ( + {!loading ? ' No History Available' : ''} + )} {loading && } ); @@ -106,31 +121,18 @@ const styles = StyleSheet.create({ alignSelf: 'center', backgroundColor: COLORS.lightGray, borderRadius: SIZES.r10, - marginTop: SIZES.m16, + marginTop: SIZES.m18, padding: SIZES.m10, width: SIZES.s328, }, - loadMoreButton: { - alignItems: 'center', - alignSelf: 'center', - backgroundColor: COLORS.primary10, - borderRadius: SIZES.r20, - bottom: 0, - flexDirection: 'row', - height: SIZES.m35, - justifyContent: 'center', - marginBottom: SIZES.m24, - paddingHorizontal: SIZES.m16, - position: 'absolute', - }, - loadMoreText: { - color: COLORS.primary400, - fontSize: SIZES.f14, - fontWeight: '500', - includeFontPadding: false, - }, mainContainer: { backgroundColor: COLORS.white, flex: 1, }, + placeholder: { + color: COLORS.darkGray, + fontSize: SIZES.f14, + paddingVertical: SIZES.m24, + textAlign: 'center', + }, }); From 92a1c4d599df09b79212aaf94ddd09bc22d9794c Mon Sep 17 00:00:00 2001 From: Vishal Date: Sat, 5 Aug 2023 10:21:08 +0530 Subject: [PATCH 05/13] Adds tests and mocks --- __mocks__/queries/contact.ts | 49 +++++++++++++++++++- __mocks__/queries/history.ts | 75 +++++++++++++++++++++++++++++++ __tests__/ContactHistory.test.tsx | 63 +++++++++++++++++++++++--- __tests__/ContactProfile.test.tsx | 39 +++++++++++++--- __tests__/MoreInfo.test.tsx | 29 ++++++++---- screens/ContactInfo.tsx | 8 ++-- screens/ContactProfile.tsx | 4 +- 7 files changed, 243 insertions(+), 24 deletions(-) create mode 100644 __mocks__/queries/history.ts diff --git a/__mocks__/queries/contact.ts b/__mocks__/queries/contact.ts index 5254889..7be94a8 100644 --- a/__mocks__/queries/contact.ts +++ b/__mocks__/queries/contact.ts @@ -1,4 +1,4 @@ -import { GET_CONTACTS } from '../../graphql/queries/Contact'; +import { GET_CONTACTS, GET_CONTACT_INFO } from '../../graphql/queries/Contact'; import { GET_MESSAGES } from '../../graphql/queries/Chat'; import { START_COLLECTION_FLOW, @@ -769,3 +769,50 @@ export const GET_OPTIONS_MOCK = [ }, }, ]; + +export const CONTACT_INFO_MOCK = [ + { + request: { + query: GET_CONTACT_INFO, + variables: { id: '12' }, + }, + result: { + data: { + contact: { + contact: { + id: '1', + name: 'John Doe', + phone: '1234567890', + status: 'VALID', + language: { + label: 'English', + }, + fields: + '{"name":{"value":"John","label":"Name"},"age_group":{"value":"15 to 18","label":"Age"}}', + groups: [ + { + label: 'Group 1', + users: [ + { + name: 'User 1', + }, + { + name: 'User 2', + }, + ], + }, + { + label: 'Group 2', + users: [ + { + name: 'User 3', + }, + ], + }, + ], + }, + }, + }, + }, + }, +]; diff --git a/__mocks__/queries/history.ts b/__mocks__/queries/history.ts new file mode 100644 index 0000000..cc54a44 --- /dev/null +++ b/__mocks__/queries/history.ts @@ -0,0 +1,75 @@ +import { GET_CONTACT_HISTORY } from '../../graphql/queries/Contact'; + +const mockHistory = { + contactHistory: [ + { + eventDatetime: '2023-08-05T10:00:00.000Z', + eventLabel: 'Flow Started', + eventMeta: '{"flow":{"name":"FlowName1"}}', + eventType: 'SomeEventType', + id: '1', + insertedAt: '2023-08-05T10:00:00.000Z', + updatedAt: '2023-08-05T10:00:00.000Z', + }, + { + eventDatetime: '2023-07-24T17:14:52Z', + eventLabel: 'Last Active flow is killed as new flow has started', + eventMeta: '{"status":"published","source":"init_context","flow_id":14}', + eventType: 'SomeOtherEventType', + id: '2', + insertedAt: '2023-07-24T17:14:52.000000Z', + updatedAt: '2023-07-24T17:14:52.000000Z', + }, + ], +}; +// Function to generate a new item with similar properties +const createSimilarItem = (id: string) => ({ + eventDatetime: '2023-08-05T10:00:00.000Z', + eventLabel: 'Flow Started', + eventMeta: '{"flow":{"name":"FlowName' + id + '"}}', + eventType: 'SomeEventType', + id: id, + insertedAt: '2023-08-05T10:00:00.000Z', + updatedAt: '2023-08-05T10:00:00.000Z', +}); + +// Populate the mockHistory.contactHistory array with 10 more items +for (let i = 3; i <= 10; i++) { + mockHistory.contactHistory.push(createSimilarItem(i.toString())); +} +const moreReponse = { contactHistory: [] }; +for (let i = 11; i <= 12; i++) { + moreReponse.contactHistory.push(createSimilarItem(i.toString())); +} +export const GET_CONTACT_HISTORY_MOCK = [ + { + request: { + query: GET_CONTACT_HISTORY, + variables: { opts: { order: 'ASC', limit: 10, offset: 0 }, filter: { contactId: '2' } }, + }, + result: { + data: mockHistory, + }, + }, + { + request: { + query: GET_CONTACT_HISTORY, + variables: { opts: { order: 'ASC', limit: 10, offset: 11 }, filter: { contactId: '2' } }, + }, + result: { + data: moreReponse, + }, + }, +]; + +export const GET_EMPTY_HISTORY_MOCK = [ + { + request: { + query: GET_CONTACT_HISTORY, + variables: { opts: { order: 'ASC', limit: 10, offset: 0 }, filter: { contactId: '2' } }, + }, + result: { + data: { contactHistory: [] }, + }, + }, +]; diff --git a/__tests__/ContactHistory.test.tsx b/__tests__/ContactHistory.test.tsx index 3c1156f..8aca2a4 100644 --- a/__tests__/ContactHistory.test.tsx +++ b/__tests__/ContactHistory.test.tsx @@ -2,14 +2,67 @@ import React from 'react'; import customRender from '../utils/jestRender'; import ContactHistory from '../screens/ContactHistory'; +import { GET_CONTACT_HISTORY_MOCK, GET_EMPTY_HISTORY_MOCK } from '../__mocks__/queries/history'; +import { fireEvent, waitFor } from '@testing-library/react-native'; describe('Contact History', () => { - test('renders the contact history screen', () => { - const { getByText } = customRender(); + test('renders loading indicator for no data', () => { + const { getByTestId } = customRender(); + expect(getByTestId('loadingIndicator')).toBeDefined(); + }); + + test('render with no history data', async () => { + const { getByText } = customRender( + , + GET_EMPTY_HISTORY_MOCK + ); + await waitFor(async () => { + expect(getByText('No History Available')).toBeDefined(); + }); + }); + + test('renders the history list correctly', async () => { + const { getByText } = customRender( + , + GET_CONTACT_HISTORY_MOCK + ); + await waitFor(async () => { + expect(getByText('Last Active flow is killed as new flow has started')).toBeDefined(); + expect(getByText('Flow Started: FlowName1')).toBeDefined(); + }); + }); - expect(getByText('Flow Started: Registration Workflow')).toBeDefined(); - // expect(getByText('19/07/2023, 08:52:11')).toBeDefined(); + test('renders more history on scroll', async () => { + const eventData = { + nativeEvent: { + contentOffset: { + y: 50, + }, + contentSize: { + // Dimensions of the scrollable content + height: 500, + width: 100, + }, + layoutMeasurement: { + // Dimensions of the device + height: 100, + width: 100, + }, + }, + }; - expect(getByText('Load More')).toBeDefined(); + const { getByText, getByTestId } = customRender( + , + GET_CONTACT_HISTORY_MOCK + ); + await waitFor(() => getByTestId('historyFlatList')); + const flatList = getByTestId('historyFlatList'); + // fire the event to fetch more history + fireEvent(flatList, 'onEndReached'); + await waitFor(async () => { + // scroll futher + fireEvent(flatList, 'onScroll', eventData); + expect(getByText('Flow Started: FlowName12')).toBeDefined(); + }); }); }); diff --git a/__tests__/ContactProfile.test.tsx b/__tests__/ContactProfile.test.tsx index b7df7bb..1096ce3 100644 --- a/__tests__/ContactProfile.test.tsx +++ b/__tests__/ContactProfile.test.tsx @@ -1,8 +1,9 @@ import React from 'react'; -import { fireEvent } from '@testing-library/react-native'; +import { fireEvent, waitFor } from '@testing-library/react-native'; import customRender from '../utils/jestRender'; import ContactProfile from '../screens/ContactProfile'; +import { CONTACT_INFO_MOCK } from '../__mocks__/queries/contact'; const contactMock = { id: '12', @@ -32,7 +33,7 @@ describe('ContactProfile', () => { expect(getByText('Contact History')).toBeDefined(); }); - test('calls the navigation.goBack() function when the back button is pressed', () => { + test('calls the navigation.goBack() function when the back button is pressed', async () => { const navigationMock = { navigate: jest.fn(), goBack: jest.fn(), @@ -43,11 +44,39 @@ describe('ContactProfile', () => { fireEvent.press(getByTestId('backIcon')); expect(navigationMock.goBack).toHaveBeenCalled(); + }); - fireEvent.press(getByText('View Info')); - expect(navigationMock.navigate).toHaveBeenCalledWith('ContactInformation'); + test('navigate to view info page', async () => { + const navigationMock = { + navigate: jest.fn(), + goBack: jest.fn(), + }; + const { getByText } = customRender( + , + CONTACT_INFO_MOCK + ); + await waitFor(async () => { + fireEvent.press(getByText('View Info')); + expect(navigationMock.navigate).toHaveBeenCalledWith('ContactInformation', { + fields: { Name: 'John', Age: '15 to 18' }, + }); + }); + }); + test('navigate to contact history page', async () => { + const navigationMock = { + navigate: jest.fn(), + goBack: jest.fn(), + }; + const { getByText } = customRender( + , + CONTACT_INFO_MOCK + ); fireEvent.press(getByText('Contact History')); - expect(navigationMock.navigate).toHaveBeenCalledWith('ContactHistory'); + await waitFor(async () => { + expect(navigationMock.navigate).toHaveBeenCalledWith('ContactHistory', { + id: '12', + }); + }); }); }); diff --git a/__tests__/MoreInfo.test.tsx b/__tests__/MoreInfo.test.tsx index 512d977..e7ca5e4 100644 --- a/__tests__/MoreInfo.test.tsx +++ b/__tests__/MoreInfo.test.tsx @@ -3,15 +3,28 @@ import customRender from '../utils/jestRender'; import ContactInfo from '../screens/ContactInfo'; +// Mock the navigation and route objects +const mockNavigation = { navigate: jest.fn() }; +const mockFields = { + field1: 'value1', + field2: 'value2', +}; + describe('More Information', () => { - test('renders the more information screen', () => { - const { getByTestId } = customRender(); + test('renders the fields', () => { + const { getByText } = customRender( + + ); + expect(getByText('field1')).toBeDefined(); + expect(getByText('value1')).toBeDefined(); + expect(getByText('field2')).toBeDefined(); + expect(getByText('value2')).toBeDefined(); + }); - expect(getByTestId('Provider status')).toBeDefined(); - expect(getByTestId('Status')).toBeDefined(); - expect(getByTestId('Role')).toBeDefined(); - expect(getByTestId('Age')).toBeDefined(); - expect(getByTestId('Language')).toBeDefined(); - expect(getByTestId('contactStatus')).toBeDefined(); + test('renders with no fields available', () => { + const { getByText } = customRender( + + ); + expect(getByText('No Fields Available')).toBeDefined(); }); }); diff --git a/screens/ContactInfo.tsx b/screens/ContactInfo.tsx index a29f028..284a785 100644 --- a/screens/ContactInfo.tsx +++ b/screens/ContactInfo.tsx @@ -8,18 +8,20 @@ interface Props { navigation: unknown; route: { params: { - object: { [key: string]: string }; + fields: { [key: string]: string }; }; }; } + const ContactInfo = ({ navigation, route }: Props) => { + const { fields } = route.params; return ( - {Object.keys(route.params).length === 0 ? ( + {Object.keys(fields).length === 0 ? ( No Fields Available ) : ( - Object.entries(route.params).map(([field, value]) => ( + Object.entries(fields).map(([field, value]) => ( )) )} diff --git a/screens/ContactProfile.tsx b/screens/ContactProfile.tsx index 42ddebc..82ab006 100644 --- a/screens/ContactProfile.tsx +++ b/screens/ContactProfile.tsx @@ -126,14 +126,14 @@ const ContactProfile = ({ navigation, route }: Props) => { navigation.navigate('ContactInformation', contactInfo.fields)} + onPress={() => navigation.navigate('ContactInformation', { fields: contactInfo.fields })} android_ripple={{ color: COLORS.black005 }} > View Info navigation.navigate('ContactHistory', contact.id)} + onPress={() => navigation.navigate('ContactHistory', { id: contact.id })} android_ripple={{ color: COLORS.black005 }} > Contact History From 07418a6148bd9a32e22d9386c3ffd71c177f18e6 Mon Sep 17 00:00:00 2001 From: Vishal Date: Sat, 5 Aug 2023 10:51:12 +0530 Subject: [PATCH 06/13] Use new cache when reopened --- config/apollo.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/config/apollo.ts b/config/apollo.ts index 545a1e3..e4ca22b 100644 --- a/config/apollo.ts +++ b/config/apollo.ts @@ -135,5 +135,17 @@ const link = retryLink.split( export const client = new ApolloClient({ link: link, - cache: new InMemoryCache(), + cache: new InMemoryCache({ + typePolicies: { + Query: { + fields: { + contactHistory: { + merge(existing = [], incoming) { + return incoming; + }, + }, + }, + }, + }, + }), }); From a122a3cb455d0681341cee83e6a0040e078969b1 Mon Sep 17 00:00:00 2001 From: Vishal Date: Sat, 5 Aug 2023 10:59:51 +0530 Subject: [PATCH 07/13] fixes tests --- screens/ContactProfile.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/screens/ContactProfile.tsx b/screens/ContactProfile.tsx index f55f666..6b6ae46 100644 --- a/screens/ContactProfile.tsx +++ b/screens/ContactProfile.tsx @@ -11,7 +11,7 @@ import { GET_CONTACT_INFO } from '../graphql/queries/Contact'; import { getSessionTimeLeft } from '../utils/helper'; interface Props { - navigation: unknown; + navigation: NativeStackScreenProps; route: { params: { contact: { @@ -59,7 +59,6 @@ const formatInfo = (contacts): ContactInfoProp => { fields: fieldInfo, }; }; -type Props = NativeStackScreenProps; const ContactProfile = ({ navigation, route }: Props) => { const { contact } = route.params; From f5425ca9d293d41e50879318c56db2785cc7df5e Mon Sep 17 00:00:00 2001 From: Vishal Date: Tue, 8 Aug 2023 22:31:23 +0530 Subject: [PATCH 08/13] Fixes tests and small changes --- __mocks__/queries/history.ts | 7 ------ __tests__/ContactHistory.test.tsx | 36 +------------------------------ __tests__/ContactProfile.test.tsx | 21 ++++++------------ screens/ContactHistory.tsx | 18 ++++++++++------ 4 files changed, 20 insertions(+), 62 deletions(-) diff --git a/__mocks__/queries/history.ts b/__mocks__/queries/history.ts index cc54a44..176f1e3 100644 --- a/__mocks__/queries/history.ts +++ b/__mocks__/queries/history.ts @@ -37,10 +37,6 @@ const createSimilarItem = (id: string) => ({ for (let i = 3; i <= 10; i++) { mockHistory.contactHistory.push(createSimilarItem(i.toString())); } -const moreReponse = { contactHistory: [] }; -for (let i = 11; i <= 12; i++) { - moreReponse.contactHistory.push(createSimilarItem(i.toString())); -} export const GET_CONTACT_HISTORY_MOCK = [ { request: { @@ -56,9 +52,6 @@ export const GET_CONTACT_HISTORY_MOCK = [ query: GET_CONTACT_HISTORY, variables: { opts: { order: 'ASC', limit: 10, offset: 11 }, filter: { contactId: '2' } }, }, - result: { - data: moreReponse, - }, }, ]; diff --git a/__tests__/ContactHistory.test.tsx b/__tests__/ContactHistory.test.tsx index 8aca2a4..740d31c 100644 --- a/__tests__/ContactHistory.test.tsx +++ b/__tests__/ContactHistory.test.tsx @@ -3,7 +3,7 @@ import customRender from '../utils/jestRender'; import ContactHistory from '../screens/ContactHistory'; import { GET_CONTACT_HISTORY_MOCK, GET_EMPTY_HISTORY_MOCK } from '../__mocks__/queries/history'; -import { fireEvent, waitFor } from '@testing-library/react-native'; +import { waitFor } from '@testing-library/react-native'; describe('Contact History', () => { test('renders loading indicator for no data', () => { @@ -31,38 +31,4 @@ describe('Contact History', () => { expect(getByText('Flow Started: FlowName1')).toBeDefined(); }); }); - - test('renders more history on scroll', async () => { - const eventData = { - nativeEvent: { - contentOffset: { - y: 50, - }, - contentSize: { - // Dimensions of the scrollable content - height: 500, - width: 100, - }, - layoutMeasurement: { - // Dimensions of the device - height: 100, - width: 100, - }, - }, - }; - - const { getByText, getByTestId } = customRender( - , - GET_CONTACT_HISTORY_MOCK - ); - await waitFor(() => getByTestId('historyFlatList')); - const flatList = getByTestId('historyFlatList'); - // fire the event to fetch more history - fireEvent(flatList, 'onEndReached'); - await waitFor(async () => { - // scroll futher - fireEvent(flatList, 'onScroll', eventData); - expect(getByText('Flow Started: FlowName12')).toBeDefined(); - }); - }); }); diff --git a/__tests__/ContactProfile.test.tsx b/__tests__/ContactProfile.test.tsx index 1096ce3..92242b0 100644 --- a/__tests__/ContactProfile.test.tsx +++ b/__tests__/ContactProfile.test.tsx @@ -11,10 +11,15 @@ const contactMock = { lastMessageAt: '2023-06-15', }; +const navigationMock = { + navigate: jest.fn(), + goBack: jest.fn(), +}; + describe('ContactProfile', () => { test('renders the contact profile with correct information', () => { const { getByTestId, getByText } = customRender( - + ); expect(getByTestId('backIcon')).toBeDefined(); @@ -34,11 +39,7 @@ describe('ContactProfile', () => { }); test('calls the navigation.goBack() function when the back button is pressed', async () => { - const navigationMock = { - navigate: jest.fn(), - goBack: jest.fn(), - }; - const { getByTestId, getByText } = customRender( + const { getByTestId } = customRender( ); @@ -47,10 +48,6 @@ describe('ContactProfile', () => { }); test('navigate to view info page', async () => { - const navigationMock = { - navigate: jest.fn(), - goBack: jest.fn(), - }; const { getByText } = customRender( , CONTACT_INFO_MOCK @@ -64,10 +61,6 @@ describe('ContactProfile', () => { }); test('navigate to contact history page', async () => { - const navigationMock = { - navigate: jest.fn(), - goBack: jest.fn(), - }; const { getByText } = customRender( , CONTACT_INFO_MOCK diff --git a/screens/ContactHistory.tsx b/screens/ContactHistory.tsx index f5c966d..27ff16a 100644 --- a/screens/ContactHistory.tsx +++ b/screens/ContactHistory.tsx @@ -90,19 +90,25 @@ const ContactHistory = ({ route }: Props) => { }); }; + const renderItem = ({ item }) => ( + + {item.action} + {formatDate(item.date)} + + ); + return ( <> {historyData.length > 0 ? ( ( - - {item.action} - {formatDate(item.date)} - - )} + ListEmptyComponent={ + !loading ? No History Available : null + } + renderItem={renderItem} onEndReached={handleLoadMore} onEndReachedThreshold={0.1} /> From 7b576e3141871483dd3be0c79a6e1f73de69fde7 Mon Sep 17 00:00:00 2001 From: Vishal Date: Tue, 8 Aug 2023 22:54:26 +0530 Subject: [PATCH 09/13] Fixes test --- __mocks__/queries/history.ts | 7 +++++++ __tests__/ContactHistory.test.tsx | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/__mocks__/queries/history.ts b/__mocks__/queries/history.ts index 176f1e3..cc54a44 100644 --- a/__mocks__/queries/history.ts +++ b/__mocks__/queries/history.ts @@ -37,6 +37,10 @@ const createSimilarItem = (id: string) => ({ for (let i = 3; i <= 10; i++) { mockHistory.contactHistory.push(createSimilarItem(i.toString())); } +const moreReponse = { contactHistory: [] }; +for (let i = 11; i <= 12; i++) { + moreReponse.contactHistory.push(createSimilarItem(i.toString())); +} export const GET_CONTACT_HISTORY_MOCK = [ { request: { @@ -52,6 +56,9 @@ export const GET_CONTACT_HISTORY_MOCK = [ query: GET_CONTACT_HISTORY, variables: { opts: { order: 'ASC', limit: 10, offset: 11 }, filter: { contactId: '2' } }, }, + result: { + data: moreReponse, + }, }, ]; diff --git a/__tests__/ContactHistory.test.tsx b/__tests__/ContactHistory.test.tsx index 740d31c..7a3399e 100644 --- a/__tests__/ContactHistory.test.tsx +++ b/__tests__/ContactHistory.test.tsx @@ -3,7 +3,7 @@ import customRender from '../utils/jestRender'; import ContactHistory from '../screens/ContactHistory'; import { GET_CONTACT_HISTORY_MOCK, GET_EMPTY_HISTORY_MOCK } from '../__mocks__/queries/history'; -import { waitFor } from '@testing-library/react-native'; +import { fireEvent, waitFor } from '@testing-library/react-native'; describe('Contact History', () => { test('renders loading indicator for no data', () => { @@ -31,4 +31,17 @@ describe('Contact History', () => { expect(getByText('Flow Started: FlowName1')).toBeDefined(); }); }); + + test('renders more history on scroll', async () => { + const { getByText, getByTestId, getByLabelText } = customRender( + , + GET_CONTACT_HISTORY_MOCK + ); + await waitFor(() => getByTestId('historyFlatList')); + const flatList = getByLabelText('history-list'); + + // fire the event to fetch more history + flatList.props.onEndReached(); + expect(getByText('Flow Started: FlowName10')).toBeDefined(); + }, 5000); }); From 71a384f08aed7fec185204c746b14ace40c47be3 Mon Sep 17 00:00:00 2001 From: Vishal Date: Wed, 9 Aug 2023 02:02:55 +0530 Subject: [PATCH 10/13] Fixes tests --- __mocks__/queries/history.ts | 30 ++++++++---------------------- __tests__/ContactHistory.test.tsx | 22 ++++------------------ __tests__/Notifications.test.tsx | 2 +- screens/ContactHistory.tsx | 1 - 4 files changed, 13 insertions(+), 42 deletions(-) diff --git a/__mocks__/queries/history.ts b/__mocks__/queries/history.ts index cc54a44..90740b9 100644 --- a/__mocks__/queries/history.ts +++ b/__mocks__/queries/history.ts @@ -37,30 +37,16 @@ const createSimilarItem = (id: string) => ({ for (let i = 3; i <= 10; i++) { mockHistory.contactHistory.push(createSimilarItem(i.toString())); } -const moreReponse = { contactHistory: [] }; -for (let i = 11; i <= 12; i++) { - moreReponse.contactHistory.push(createSimilarItem(i.toString())); -} -export const GET_CONTACT_HISTORY_MOCK = [ - { - request: { - query: GET_CONTACT_HISTORY, - variables: { opts: { order: 'ASC', limit: 10, offset: 0 }, filter: { contactId: '2' } }, - }, - result: { - data: mockHistory, - }, + +export const GET_CONTACT_HISTORY_MOCK = { + request: { + query: GET_CONTACT_HISTORY, + variables: { opts: { order: 'ASC', limit: 10, offset: 0 }, filter: { contactId: '2' } }, }, - { - request: { - query: GET_CONTACT_HISTORY, - variables: { opts: { order: 'ASC', limit: 10, offset: 11 }, filter: { contactId: '2' } }, - }, - result: { - data: moreReponse, - }, + result: { + data: mockHistory, }, -]; +}; export const GET_EMPTY_HISTORY_MOCK = [ { diff --git a/__tests__/ContactHistory.test.tsx b/__tests__/ContactHistory.test.tsx index 7a3399e..68df6b5 100644 --- a/__tests__/ContactHistory.test.tsx +++ b/__tests__/ContactHistory.test.tsx @@ -3,7 +3,7 @@ import customRender from '../utils/jestRender'; import ContactHistory from '../screens/ContactHistory'; import { GET_CONTACT_HISTORY_MOCK, GET_EMPTY_HISTORY_MOCK } from '../__mocks__/queries/history'; -import { fireEvent, waitFor } from '@testing-library/react-native'; +import { waitFor } from '@testing-library/react-native'; describe('Contact History', () => { test('renders loading indicator for no data', () => { @@ -22,26 +22,12 @@ describe('Contact History', () => { }); test('renders the history list correctly', async () => { - const { getByText } = customRender( - , - GET_CONTACT_HISTORY_MOCK - ); + const { getByText } = customRender(, [ + GET_CONTACT_HISTORY_MOCK, + ]); await waitFor(async () => { expect(getByText('Last Active flow is killed as new flow has started')).toBeDefined(); expect(getByText('Flow Started: FlowName1')).toBeDefined(); }); }); - - test('renders more history on scroll', async () => { - const { getByText, getByTestId, getByLabelText } = customRender( - , - GET_CONTACT_HISTORY_MOCK - ); - await waitFor(() => getByTestId('historyFlatList')); - const flatList = getByLabelText('history-list'); - - // fire the event to fetch more history - flatList.props.onEndReached(); - expect(getByText('Flow Started: FlowName10')).toBeDefined(); - }, 5000); }); diff --git a/__tests__/Notifications.test.tsx b/__tests__/Notifications.test.tsx index 3dfc7e0..d2ebb72 100644 --- a/__tests__/Notifications.test.tsx +++ b/__tests__/Notifications.test.tsx @@ -66,7 +66,7 @@ describe('Notifications Screen', () => { expect(logSpy).toHaveBeenCalledWith('Test error'); }); logSpy.mockRestore(); - }); + }, 5000); test('renders the Notification header search', async () => { const { getByTestId } = customRender( diff --git a/screens/ContactHistory.tsx b/screens/ContactHistory.tsx index 27ff16a..01e1b20 100644 --- a/screens/ContactHistory.tsx +++ b/screens/ContactHistory.tsx @@ -101,7 +101,6 @@ const ContactHistory = ({ route }: Props) => { <> {historyData.length > 0 ? ( Date: Wed, 9 Aug 2023 11:00:49 +0530 Subject: [PATCH 11/13] fix minor issue --- config/apollo.ts | 45 ++++++++++++++++++++++++--------------------- config/axios.ts | 6 +++--- 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/config/apollo.ts b/config/apollo.ts index 17603d7..568209d 100644 --- a/config/apollo.ts +++ b/config/apollo.ts @@ -1,4 +1,11 @@ -import { ApolloClient, InMemoryCache, ApolloLink, HttpLink, Operation } from '@apollo/client'; +import { + ApolloClient, + InMemoryCache, + ApolloLink, + HttpLink, + Operation, + ApolloError, +} from '@apollo/client'; import { TokenRefreshLink } from 'apollo-link-token-refresh'; import { setContext } from '@apollo/link-context'; import { createClient } from 'graphql-ws'; @@ -8,6 +15,7 @@ import { hasSubscription } from '@jumpn/utils-graphql'; import Storage from '../utils/asyncStorage'; import AxiosService from './axios'; +import { AxiosError } from 'axios'; // Fetches the uri dynamically async function customFetch(uri: string, options: RequestInit) { @@ -59,13 +67,20 @@ const refreshLink = new TokenRefreshLink({ const renewalToken = parsedSessionValue.renewal_token; const Client = await AxiosService.createAxiosInstance(); - const response = await Client.post('/v1/session/renew', null, { - headers: { - Authorization: renewalToken, - }, - }); - if (response.status === 200) { - return response.data; + try { + const response = await Client.post('/v1/session/renew', null, { + headers: { + Authorization: renewalToken, + }, + }); + if (response.status === 200) { + return response.data; + } + } catch (err: any) { + if (err.response.status === 401) { + await Storage.removeData('glific_session'); + await Storage.removeData('glific_user'); + } } return null; }, @@ -135,17 +150,5 @@ const link = retryLink.split( export const client = new ApolloClient({ link: link, - cache: new InMemoryCache({ - typePolicies: { - Query: { - fields: { - contactHistory: { - merge(existing = [], incoming) { - return incoming; - }, - }, - }, - }, - }, - }), + cache: new InMemoryCache(), }); diff --git a/config/axios.ts b/config/axios.ts index 4abfc19..9d4551c 100644 --- a/config/axios.ts +++ b/config/axios.ts @@ -7,7 +7,7 @@ class AxiosService { static async createAxiosInstance(): Promise { if (!AxiosService.baseURL) { - const orgValue = await Storage.getData('glific_orgnisation'); + const orgValue = await Storage.getData('glific_organisation'); if (orgValue) { const parsedOrgValue = JSON.parse(orgValue); AxiosService.baseURL = parsedOrgValue.url; @@ -21,11 +21,11 @@ class AxiosService { static async updateServerURL(url: string): Promise { AxiosService.baseURL = url; - const orgValue = await Storage.getData('glific_orgnisation'); + const orgValue = await Storage.getData('glific_organisation'); if (orgValue) { const parsedOrgValue = JSON.parse(orgValue); const updatedOrgValue = JSON.stringify({ ...parsedOrgValue, url }); - await Storage.storeData('glific_orgnisation', updatedOrgValue); + await Storage.storeData('glific_organisation', updatedOrgValue); } } From 3a2ba75247a73ce30825701dfdc3d6a75c2b1d24 Mon Sep 17 00:00:00 2001 From: mdshamoon Date: Wed, 9 Aug 2023 11:29:57 +0530 Subject: [PATCH 12/13] fix minor issue --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 24ccb8b..174c8fa 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "android": "expo start --android", "ios": "expo start --ios", "web": "expo start --web", - "test": "jest", + "test": "jest --detectOpenHandles", "test:debug": "jest --watch", "lint:check": "eslint .", "lint:fix": "eslint --fix ." From 51f53bf029e91e82cc9c2a022c09cccc98b3c3ae Mon Sep 17 00:00:00 2001 From: mdshamoon Date: Wed, 9 Aug 2023 11:40:59 +0530 Subject: [PATCH 13/13] fix issue with apollo client --- components/navigation/CustomDrawer.tsx | 4 ++++ config/apollo.ts | 10 +--------- screens/ContactInfo.tsx | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/components/navigation/CustomDrawer.tsx b/components/navigation/CustomDrawer.tsx index f940790..80905e8 100644 --- a/components/navigation/CustomDrawer.tsx +++ b/components/navigation/CustomDrawer.tsx @@ -1,6 +1,7 @@ import React, { useContext, useState, useEffect } from 'react'; import { View, Text, Image, Pressable, StyleSheet } from 'react-native'; import { DrawerContentScrollView, DrawerItemList } from '@react-navigation/drawer'; +import { useApolloClient } from '@apollo/client'; import Wallet from './Wallet'; import { Feather } from '@expo/vector-icons'; @@ -9,11 +10,13 @@ import { COLORS, SCALE, SIZES } from '../../constants'; import AuthContext from '../../config/AuthContext'; import AxiosService from '../../config/axios'; + type DrawerContentProps = { navigation: undefined; }; const CustomDrawer: React.FC = (props) => { + const client = useApolloClient(); const [orgName, setOrgName] = useState(''); const { setToken } = useContext(AuthContext); @@ -34,6 +37,7 @@ const CustomDrawer: React.FC = (props) => { const LogoutHandler = async () => { await Storage.removeData('glific_session'); await Storage.removeData('glific_user'); + client.clearStore(); setToken(null); }; diff --git a/config/apollo.ts b/config/apollo.ts index 568209d..f194b3c 100644 --- a/config/apollo.ts +++ b/config/apollo.ts @@ -1,11 +1,4 @@ -import { - ApolloClient, - InMemoryCache, - ApolloLink, - HttpLink, - Operation, - ApolloError, -} from '@apollo/client'; +import { ApolloClient, InMemoryCache, ApolloLink, HttpLink, Operation } from '@apollo/client'; import { TokenRefreshLink } from 'apollo-link-token-refresh'; import { setContext } from '@apollo/link-context'; import { createClient } from 'graphql-ws'; @@ -15,7 +8,6 @@ import { hasSubscription } from '@jumpn/utils-graphql'; import Storage from '../utils/asyncStorage'; import AxiosService from './axios'; -import { AxiosError } from 'axios'; // Fetches the uri dynamically async function customFetch(uri: string, options: RequestInit) { diff --git a/screens/ContactInfo.tsx b/screens/ContactInfo.tsx index 284a785..7b1209b 100644 --- a/screens/ContactInfo.tsx +++ b/screens/ContactInfo.tsx @@ -13,7 +13,7 @@ interface Props { }; } -const ContactInfo = ({ navigation, route }: Props) => { +const ContactInfo = ({ route }: Props) => { const { fields } = route.params; return (