TP-62631 | Exotel call recording
This commit is contained in:
@@ -10,6 +10,7 @@ import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
||||
import com.avapp.deviceDataSync.DeviceDataSyncPackage;
|
||||
import com.avapp.phoneStateBroadcastReceiver.PhoneStateModulePackage;
|
||||
import com.avapp.utils.FirebaseRemoteConfigHelper;
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactApplication;
|
||||
@@ -56,6 +57,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
packages.add(new DeviceUtilsModulePackage());
|
||||
packages.add(new ScreenshotBlockerModulePackage());
|
||||
packages.add(new DeviceDataSyncPackage());
|
||||
packages.add(new PhoneStateModulePackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.avapp.phoneStateBroadcastReceiver;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.IntentFilter;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.modules.core.DeviceEventManagerModule;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.telephony.PhoneStateListener;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
|
||||
public class PhoneStateModule extends ReactContextBaseJavaModule {
|
||||
private final ReactApplicationContext reactContext;
|
||||
private TelephonyManager telephonyManager;
|
||||
private String currentCallState = "UNKNOWN";
|
||||
|
||||
public PhoneStateModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
this.reactContext = reactContext;
|
||||
telephonyManager = (TelephonyManager) reactContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "PhoneStateModule";
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getCurrentCallState(Promise promise) {
|
||||
int state = telephonyManager.getCallState();
|
||||
String currentCallState;
|
||||
|
||||
switch (state) {
|
||||
case TelephonyManager.CALL_STATE_IDLE:
|
||||
currentCallState = "IDLE";
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_RINGING:
|
||||
currentCallState = "RINGING";
|
||||
break;
|
||||
case TelephonyManager.CALL_STATE_OFFHOOK:
|
||||
currentCallState = "OFFHOOK";
|
||||
break;
|
||||
default:
|
||||
currentCallState = "UNKNOWN";
|
||||
break;
|
||||
}
|
||||
|
||||
promise.resolve(currentCallState);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.avapp.phoneStateBroadcastReceiver;
|
||||
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class PhoneStateModulePackage implements ReactPackage {
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(
|
||||
ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
|
||||
modules.add(new PhoneStateModule(reactContext));
|
||||
|
||||
return modules;
|
||||
}
|
||||
}
|
||||
16
src/action/callRecordingActions.ts
Normal file
16
src/action/callRecordingActions.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import axiosInstance, { ApiKeys, getApiUrl } from '@components/utlis/apiHelper';
|
||||
import { logError } from '@components/utlis/errorUtils';
|
||||
import { setConnectingToCustomerBottomSheet } from '@reducers/activeCallSlice';
|
||||
import { AppDispatch } from '@store';
|
||||
|
||||
export const makeACallToCustomer = (payload: any) => (dispatch: AppDispatch) => {
|
||||
const url = getApiUrl(ApiKeys.CALL_CUSTOMER);
|
||||
dispatch(setConnectingToCustomerBottomSheet(true));
|
||||
axiosInstance
|
||||
.post(url, payload)
|
||||
.then((res) => {})
|
||||
.catch((err: Error) => {
|
||||
logError(err);
|
||||
})
|
||||
.finally(() => {});
|
||||
};
|
||||
@@ -4,7 +4,7 @@ import { logError } from '../components/utlis/errorUtils';
|
||||
import {
|
||||
ITelephoneNumbers,
|
||||
setCallHistory,
|
||||
setTelephoneNumbers,
|
||||
setTelephoneDetails,
|
||||
} from '@reducers/telephoneNumbersSlice';
|
||||
import { isFunction } from '@components/utlis/commonFunctions';
|
||||
|
||||
@@ -84,9 +84,12 @@ export const fetchTelephoneNumber =
|
||||
new: false,
|
||||
},
|
||||
],
|
||||
agentCallActivity: null,
|
||||
agentCallActivity: {
|
||||
genuineCallCount: 3,
|
||||
enableFeature: false,
|
||||
},
|
||||
};
|
||||
dispatch(setTelephoneNumbers({ caseId: caseId, telephoneNumbers: response.telephones }));
|
||||
dispatch(setTelephoneDetails({ caseId: caseId, data: response }));
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
logError(err);
|
||||
|
||||
5
src/components/utlis/PhoneState.ts
Normal file
5
src/components/utlis/PhoneState.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { NativeModules } from 'react-native';
|
||||
|
||||
const { PhoneStateModule } = NativeModules;
|
||||
|
||||
export default PhoneStateModule;
|
||||
@@ -85,6 +85,7 @@ export enum ApiKeys {
|
||||
DUE_AMOUNT_SUMMARY = 'DUE_AMOUNT_SUMMARY',
|
||||
FEE_WAIVER_HISTORY = 'FEE_WAIVER_HISTORY',
|
||||
FEE_WAIVER_V2 = 'FEE_WAIVER_V2',
|
||||
CALL_CUSTOMER = 'CALL_CUSTOMER',
|
||||
}
|
||||
|
||||
export const API_URLS: Record<ApiKeys, string> = {} as Record<ApiKeys, string>;
|
||||
@@ -161,6 +162,7 @@ API_URLS[ApiKeys.GET_UPDATE_COUNT] = '/support-requests/summary';
|
||||
API_URLS[ApiKeys.DUE_AMOUNT_SUMMARY] = '/collection-cases/{loanAccountNumber}/amount-summary';
|
||||
API_URLS[ApiKeys.FEE_WAIVER_HISTORY] = '/collection-cases/{loanAccountNumber}/waiver-history';
|
||||
API_URLS[ApiKeys.FEE_WAIVER_V2] = '/loan/request/{loanAccountNumber}/adjust-component/v2';
|
||||
API_URLS[ApiKeys.CALL_CUSTOMER] = '/call';
|
||||
|
||||
export const API_STATUS_CODE = {
|
||||
OK: 200,
|
||||
|
||||
@@ -2,10 +2,11 @@ import { createSlice } from '@reduxjs/toolkit';
|
||||
|
||||
const initialState = {
|
||||
phoneNumber: '98989898998',
|
||||
referenceId: 'fdc99092-6155-438f-895e-81dc75d3efe0',
|
||||
customerName: 'Test User',
|
||||
caseId: '2875116',
|
||||
showConnectingToCustomerBottomSheet: false,
|
||||
showCallCannotInitiateBottomSheet: true,
|
||||
showCallCannotInitiateBottomSheet: false,
|
||||
};
|
||||
|
||||
export const activeCallSlice = createSlice({
|
||||
|
||||
@@ -24,6 +24,10 @@ interface ITelephoneNumbersSlice {
|
||||
callHistory: {
|
||||
[key: string]: any[];
|
||||
};
|
||||
callActivity: {
|
||||
[key: string]: any;
|
||||
};
|
||||
callAttemptedOn: string;
|
||||
}
|
||||
|
||||
interface SetTelephoneNumbersActionType {
|
||||
@@ -36,6 +40,8 @@ interface SetTelephoneNumbersActionType {
|
||||
const initialState: ITelephoneNumbersSlice = {
|
||||
telephoneNumbers: {},
|
||||
callHistory: {},
|
||||
callActivity: {},
|
||||
callAttemptedOn: '',
|
||||
};
|
||||
|
||||
export const telephoneNumbersSlice = createSlice({
|
||||
@@ -48,9 +54,20 @@ export const telephoneNumbersSlice = createSlice({
|
||||
setCallHistory: (state, action) => {
|
||||
state.callHistory[action?.payload?.caseId] = action?.payload?.callHistory;
|
||||
},
|
||||
setCallActivity: (state, action) => {
|
||||
state.callActivity[action?.payload?.caseId] = action.payload.agentCallActivity;
|
||||
},
|
||||
setTelephoneDetails: (state, action) => {
|
||||
state.telephoneNumbers[action?.payload?.caseId] = action?.payload?.data?.telephones;
|
||||
state.callActivity[action?.payload?.caseId] = action?.payload?.data?.agentCallActivity;
|
||||
},
|
||||
setCallAttemptedOn: (state, action) => {
|
||||
state.callAttemptedOn = action.payload;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const { setTelephoneNumbers, setCallHistory } = telephoneNumbersSlice.actions;
|
||||
export const { setTelephoneNumbers, setCallHistory, setTelephoneDetails, setCallAttemptedOn } =
|
||||
telephoneNumbersSlice.actions;
|
||||
|
||||
export default telephoneNumbersSlice.reducer;
|
||||
|
||||
@@ -6,8 +6,7 @@ import NavigationHeader, { Icon } from '../../../RN-UI-LIB/src/components/Naviga
|
||||
import TextInput from '../../../RN-UI-LIB/src/components/TextInput';
|
||||
import Button from '../../../RN-UI-LIB/src/components/Button';
|
||||
import { popToScreen } from '../../components/utlis/navigationUtlis';
|
||||
import { GenericStyles, getShadowStyle } from '../../../RN-UI-LIB/src/styles';
|
||||
import Dropdown from '../../../RN-UI-LIB/src/components/dropdown/Dropdown';
|
||||
import { GenericStyles } from '../../../RN-UI-LIB/src/styles';
|
||||
import { Controller, useForm } from 'react-hook-form';
|
||||
import { Source, Tag } from './const';
|
||||
import DropdownItem from '../registerPayements/DropdownItem';
|
||||
@@ -84,117 +83,99 @@ const AddNewNumber: React.FC<IAddNewNumber> = (props) => {
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<SafeAreaView
|
||||
style={[
|
||||
GenericStyles.whiteBackground,
|
||||
{
|
||||
height: '100%',
|
||||
},
|
||||
]}
|
||||
>
|
||||
<SafeAreaView style={GenericStyles.fill}>
|
||||
<NavigationHeader title="Adding new number" icon={Icon.close} onBack={onBack} />
|
||||
<View style={[GenericStyles.ph16, GenericStyles.pv24]}>
|
||||
<View
|
||||
style={[
|
||||
GenericStyles.ph16,
|
||||
GenericStyles.pt16,
|
||||
GenericStyles.pb24,
|
||||
getShadowStyle(8),
|
||||
GenericStyles.whiteBackground,
|
||||
]}
|
||||
>
|
||||
<View style={[GenericStyles.mb24]}>
|
||||
<Text bold dark style={[GenericStyles.mb8]}>
|
||||
Add new number
|
||||
</Text>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({ field: { onChange, onBlur, value } }) => (
|
||||
<TextInput
|
||||
value={value}
|
||||
onChangeText={(number) => {
|
||||
onChange(number);
|
||||
trigger();
|
||||
}}
|
||||
keyboardType="numeric"
|
||||
placeholder="Enter here"
|
||||
maxLength={10}
|
||||
/>
|
||||
)}
|
||||
name="number"
|
||||
rules={{
|
||||
required: true,
|
||||
minLength: 10,
|
||||
min: 10,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<View style={[GenericStyles.mb24]}>
|
||||
<Text bold dark style={[GenericStyles.mb8]}>
|
||||
Source of the number
|
||||
</Text>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({ field: { onChange, onBlur, value } }) => (
|
||||
<DropDownWrapper
|
||||
placeholder="Select"
|
||||
onValueChange={(number) => {
|
||||
onChange(number);
|
||||
trigger();
|
||||
}}
|
||||
bottomSheetHeight={getBottomSheetHeight(Object.values(Source).length)}
|
||||
header="Source of the number"
|
||||
value={value ?? ''}
|
||||
>
|
||||
{SourceChildComponents}
|
||||
</DropDownWrapper>
|
||||
)}
|
||||
name="source"
|
||||
rules={{ required: true }}
|
||||
/>
|
||||
</View>
|
||||
<View style={[GenericStyles.mb24]}>
|
||||
<Text bold dark style={[GenericStyles.mb8]}>
|
||||
Tag number
|
||||
</Text>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({ field: { onChange, onBlur, value } }) => (
|
||||
<DropDownWrapper
|
||||
placeholder="Select"
|
||||
onValueChange={(number) => {
|
||||
onChange(number);
|
||||
trigger();
|
||||
}}
|
||||
bottomSheetHeight={getBottomSheetHeight(Object.values(Tag).length)}
|
||||
header="Tag number"
|
||||
value={value ?? ''}
|
||||
>
|
||||
{TagChildComponents}
|
||||
</DropDownWrapper>
|
||||
)}
|
||||
name="tag"
|
||||
rules={{ required: true }}
|
||||
/>
|
||||
<View style={[GenericStyles.fill, GenericStyles.justifyContentFlexEnd]}>
|
||||
<View style={[GenericStyles.ph16, GenericStyles.pv16]}>
|
||||
<View style={GenericStyles.pt16}>
|
||||
<View style={[GenericStyles.mb24]}>
|
||||
<Text bold dark style={[GenericStyles.mb8]}>
|
||||
Add new number
|
||||
</Text>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({ field: { onChange, onBlur, value } }) => (
|
||||
<TextInput
|
||||
value={value}
|
||||
onChangeText={(number) => {
|
||||
onChange(number);
|
||||
trigger();
|
||||
}}
|
||||
keyboardType="numeric"
|
||||
placeholder="Enter here"
|
||||
maxLength={10}
|
||||
/>
|
||||
)}
|
||||
name="number"
|
||||
rules={{
|
||||
required: true,
|
||||
minLength: 10,
|
||||
min: 10,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
<View style={[GenericStyles.mb24]}>
|
||||
<Text bold dark style={[GenericStyles.mb8]}>
|
||||
Source of the number
|
||||
</Text>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({ field: { onChange, onBlur, value } }) => (
|
||||
<DropDownWrapper
|
||||
placeholder="Select"
|
||||
onValueChange={(number) => {
|
||||
onChange(number);
|
||||
trigger();
|
||||
}}
|
||||
containerStyle={GenericStyles.whiteBackground}
|
||||
bottomSheetHeight={getBottomSheetHeight(Object.values(Source).length)}
|
||||
header="Source of the number"
|
||||
value={value ?? ''}
|
||||
>
|
||||
{SourceChildComponents}
|
||||
</DropDownWrapper>
|
||||
)}
|
||||
name="source"
|
||||
rules={{ required: true }}
|
||||
/>
|
||||
</View>
|
||||
<View style={[GenericStyles.mb24]}>
|
||||
<Text bold dark style={[GenericStyles.mb8]}>
|
||||
Tag number
|
||||
</Text>
|
||||
<Controller
|
||||
control={control}
|
||||
render={({ field: { onChange, onBlur, value } }) => (
|
||||
<DropDownWrapper
|
||||
placeholder="Select"
|
||||
onValueChange={(number) => {
|
||||
onChange(number);
|
||||
trigger();
|
||||
}}
|
||||
containerStyle={GenericStyles.whiteBackground}
|
||||
bottomSheetHeight={getBottomSheetHeight(Object.values(Tag).length)}
|
||||
header="Tag number"
|
||||
value={value ?? ''}
|
||||
>
|
||||
{TagChildComponents}
|
||||
</DropDownWrapper>
|
||||
)}
|
||||
name="tag"
|
||||
rules={{ required: true }}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={[
|
||||
GenericStyles.mt24,
|
||||
GenericStyles.w100,
|
||||
styles.buttonContainer,
|
||||
GenericStyles.ph16,
|
||||
]}
|
||||
>
|
||||
<Button
|
||||
variant="primary"
|
||||
title="Add"
|
||||
disabled={!isValid || !(getValues('number')?.length > 0)}
|
||||
style={[GenericStyles.w100]}
|
||||
onPress={addCtaHandler}
|
||||
showLoader={loading}
|
||||
/>
|
||||
<View style={[GenericStyles.mb24, GenericStyles.w100, GenericStyles.ph16]}>
|
||||
<Button
|
||||
variant="primary"
|
||||
title="Add"
|
||||
disabled={!isValid || !(getValues('number')?.length > 0)}
|
||||
style={[GenericStyles.w100]}
|
||||
onPress={addCtaHandler}
|
||||
showLoader={loading}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</SafeAreaView>
|
||||
</Layout>
|
||||
@@ -212,10 +193,6 @@ const styles = StyleSheet.create({
|
||||
shadowRadius: 20,
|
||||
borderRadius: 8,
|
||||
},
|
||||
buttonContainer: {
|
||||
bottom: 24,
|
||||
position: 'absolute',
|
||||
},
|
||||
});
|
||||
|
||||
export default AddNewNumber;
|
||||
|
||||
@@ -9,20 +9,20 @@ import CallingFlow from './CallingFlow';
|
||||
import { ICallCustomer } from './CallingFlow/interfaces';
|
||||
|
||||
const CallCustomer: React.FC<ICallCustomer> = (props) => {
|
||||
// const {
|
||||
// route: {
|
||||
// params: { caseId },
|
||||
// },
|
||||
// } = props;
|
||||
const caseId = '2875116';
|
||||
const caseDetail =
|
||||
useAppSelector((state: RootState) => state?.allCases?.caseDetails[caseId]) || {};
|
||||
const {
|
||||
route: {
|
||||
params: { caseId },
|
||||
},
|
||||
} = props;
|
||||
// const caseId = '2875116';
|
||||
const customerName =
|
||||
useAppSelector((state: RootState) => state?.allCases?.caseDetails[caseId]?.customerName);
|
||||
|
||||
const isExternalAgent = useAppSelector((state: RootState) => state?.user?.isExternalAgent);
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<NavigationHeader title={`Call ${caseDetail?.customerName}`} onBack={goBack} />
|
||||
<NavigationHeader title={`Call ${customerName}`} onBack={goBack} />
|
||||
{!isExternalAgent ? <CallingFlow caseId={caseId} /> : <CustomerNumbers caseId={caseId} />}
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -5,11 +5,12 @@ import Button from '@rn-ui-lib/components/Button';
|
||||
import Text from '@rn-ui-lib/components/Text';
|
||||
import { GenericStyles } from '@rn-ui-lib/styles';
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { G, Mask, Path, Rect, Svg } from 'react-native-svg';
|
||||
import { Pressable, StyleSheet, View } from 'react-native';
|
||||
import { RootState } from '@store';
|
||||
import { useAppDispatch, useAppSelector } from '@hooks';
|
||||
import { setCallCannotInitiateBottomSheet } from '@reducers/activeCallSlice';
|
||||
import CallCannotInitiatedIcon from '@rn-ui-lib/icons/CallCannotInitiatedIcon';
|
||||
import CrossIcon_20 from '@rn-ui-lib/icons/CrossIcon_20';
|
||||
|
||||
const CallCannotInitiateBottomSheet = () => {
|
||||
const showCallCannotInitiateBottomSheet =
|
||||
@@ -22,44 +23,40 @@ const CallCannotInitiateBottomSheet = () => {
|
||||
dispatch(setCallCannotInitiateBottomSheet(!showCallCannotInitiateBottomSheet));
|
||||
};
|
||||
|
||||
const height = getDynamicBottomSheetHeightPercentageFn(100, 70);
|
||||
const height = getDynamicBottomSheetHeightPercentageFn(100, 60);
|
||||
|
||||
return (
|
||||
<BottomSheetWrapper
|
||||
heightPercentage={height(5)}
|
||||
visible={!showCallCannotInitiateBottomSheet}
|
||||
heightPercentage={height(4.5)}
|
||||
visible={showCallCannotInitiateBottomSheet}
|
||||
HeaderNode={() => (
|
||||
<View style={[GenericStyles.alignItemsFlexEnd, GenericStyles.ph16]}>
|
||||
<Svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
||||
<Mask
|
||||
id="mask0_17037_101993"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="0"
|
||||
y="0"
|
||||
width="20"
|
||||
height="20"
|
||||
>
|
||||
<Rect width="20" height="20" fill="#D9D9D9" />
|
||||
</Mask>
|
||||
<G mask="url(#mask0_17037_101993)">
|
||||
<Path
|
||||
d="M9.9987 11.1654L5.91536 15.2487C5.76259 15.4015 5.56814 15.4779 5.33203 15.4779C5.09592 15.4779 4.90148 15.4015 4.7487 15.2487C4.59592 15.0959 4.51953 14.9015 4.51953 14.6654C4.51953 14.4293 4.59592 14.2348 4.7487 14.082L8.83203 9.9987L4.7487 5.91536C4.59592 5.76259 4.51953 5.56814 4.51953 5.33203C4.51953 5.09592 4.59592 4.90148 4.7487 4.7487C4.90148 4.59592 5.09592 4.51953 5.33203 4.51953C5.56814 4.51953 5.76259 4.59592 5.91536 4.7487L9.9987 8.83203L14.082 4.7487C14.2348 4.59592 14.4293 4.51953 14.6654 4.51953C14.9015 4.51953 15.0959 4.59592 15.2487 4.7487C15.4015 4.90148 15.4779 5.09592 15.4779 5.33203C15.4779 5.56814 15.4015 5.76259 15.2487 5.91536L11.1654 9.9987L15.2487 14.082C15.4015 14.2348 15.4779 14.4293 15.4779 14.6654C15.4779 14.9015 15.4015 15.0959 15.2487 15.2487C15.0959 15.4015 14.9015 15.4779 14.6654 15.4779C14.4293 15.4779 14.2348 15.4015 14.082 15.2487L9.9987 11.1654Z"
|
||||
fill="#969696"
|
||||
/>
|
||||
</G>
|
||||
</Svg>
|
||||
</View>
|
||||
<Pressable
|
||||
onPress={hideBottomSheet}
|
||||
style={[GenericStyles.alignItemsFlexEnd, GenericStyles.ph16]}
|
||||
>
|
||||
<CrossIcon_20 />
|
||||
</Pressable>
|
||||
)}
|
||||
setVisible={hideBottomSheet}
|
||||
>
|
||||
<View style={[GenericStyles.ph16]}>
|
||||
<View style={{ paddingHorizontal: 30 }}>
|
||||
<Text style={styles.headerTxt}>Call cannot be initiated!</Text>
|
||||
<Text style={styles.descriptionTxt}>
|
||||
There is already an ongoing call with <Text style={styles.name}>Abhinav</Text> on{' '}
|
||||
<Text style={styles.phoneNumber}>XXXXXX9544</Text>. Try calling after ending the current
|
||||
call
|
||||
</Text>
|
||||
<View
|
||||
style={[
|
||||
GenericStyles.ph16,
|
||||
GenericStyles.pv24,
|
||||
GenericStyles.fill,
|
||||
GenericStyles.justifyContentSpaceBetween,
|
||||
]}
|
||||
>
|
||||
<View style={GenericStyles.alignCenter}>
|
||||
<CallCannotInitiatedIcon />
|
||||
<View style={{ paddingHorizontal: 30, paddingTop: 24 }}>
|
||||
<Text style={styles.headerTxt}>Call cannot be initiated!</Text>
|
||||
<Text style={styles.descriptionTxt}>
|
||||
There is already an ongoing call with <Text style={styles.name}>Abhinav</Text> on{' '}
|
||||
<Text style={styles.phoneNumber}>XXXXXX9544</Text>. Try calling after ending the
|
||||
current call
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<Button title="Understood" onPress={hideBottomSheet} style={[GenericStyles.w100]} />
|
||||
|
||||
@@ -5,64 +5,70 @@ import Button from '@rn-ui-lib/components/Button';
|
||||
import Text from '@rn-ui-lib/components/Text';
|
||||
import { GenericStyles } from '@rn-ui-lib/styles';
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { G, Mask, Path, Rect, Svg } from 'react-native-svg';
|
||||
import { Pressable, StyleSheet, View } from 'react-native';
|
||||
import { useAppDispatch, useAppSelector } from '@hooks';
|
||||
import { RootState } from '@store';
|
||||
import { setConnectingToCustomerBottomSheet } from '@reducers/activeCallSlice';
|
||||
import ConnectingToCustomerIcon from '@rn-ui-lib/icons/ConnectingToCustomerIcon';
|
||||
import CrossIcon_20 from '@rn-ui-lib/icons/CrossIcon_20';
|
||||
import { IConnectingToCustomerBottomSheet } from '../interfaces';
|
||||
|
||||
const ConnectingToCustomerBottomSheet = () => {
|
||||
const ConnectingToCustomerBottomSheet = (props: IConnectingToCustomerBottomSheet) => {
|
||||
const { caseId } = props;
|
||||
const showConnectingToCustomerBottomSheet =
|
||||
useAppSelector((state: RootState) => state?.activeCall?.showConnectingToCustomerBottomSheet) ||
|
||||
false;
|
||||
|
||||
const customerName = useAppSelector(
|
||||
(state: RootState) => state?.allCases?.caseDetails[caseId]?.customerName
|
||||
);
|
||||
|
||||
const callAttemptedOn = useAppSelector(
|
||||
(state: RootState) => state?.telephoneNumbers?.callAttemptedOn
|
||||
);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const hideBottomSheet = () => {
|
||||
dispatch(setConnectingToCustomerBottomSheet(false));
|
||||
};
|
||||
|
||||
const height = getDynamicBottomSheetHeightPercentageFn(100, 70);
|
||||
const height = getDynamicBottomSheetHeightPercentageFn(100, 60);
|
||||
|
||||
return (
|
||||
<BottomSheetWrapper
|
||||
heightPercentage={height(5)}
|
||||
heightPercentage={height(4.5)}
|
||||
visible={showConnectingToCustomerBottomSheet}
|
||||
HeaderNode={() => (
|
||||
<View style={[GenericStyles.alignItemsFlexEnd, GenericStyles.ph16]}>
|
||||
<Svg width="20" height="20" viewBox="0 0 20 20" fill="none">
|
||||
<Mask
|
||||
id="mask0_17037_101993"
|
||||
maskUnits="userSpaceOnUse"
|
||||
x="0"
|
||||
y="0"
|
||||
width="20"
|
||||
height="20"
|
||||
>
|
||||
<Rect width="20" height="20" fill="#D9D9D9" />
|
||||
</Mask>
|
||||
<G mask="url(#mask0_17037_101993)">
|
||||
<Path
|
||||
d="M9.9987 11.1654L5.91536 15.2487C5.76259 15.4015 5.56814 15.4779 5.33203 15.4779C5.09592 15.4779 4.90148 15.4015 4.7487 15.2487C4.59592 15.0959 4.51953 14.9015 4.51953 14.6654C4.51953 14.4293 4.59592 14.2348 4.7487 14.082L8.83203 9.9987L4.7487 5.91536C4.59592 5.76259 4.51953 5.56814 4.51953 5.33203C4.51953 5.09592 4.59592 4.90148 4.7487 4.7487C4.90148 4.59592 5.09592 4.51953 5.33203 4.51953C5.56814 4.51953 5.76259 4.59592 5.91536 4.7487L9.9987 8.83203L14.082 4.7487C14.2348 4.59592 14.4293 4.51953 14.6654 4.51953C14.9015 4.51953 15.0959 4.59592 15.2487 4.7487C15.4015 4.90148 15.4779 5.09592 15.4779 5.33203C15.4779 5.56814 15.4015 5.76259 15.2487 5.91536L11.1654 9.9987L15.2487 14.082C15.4015 14.2348 15.4779 14.4293 15.4779 14.6654C15.4779 14.9015 15.4015 15.0959 15.2487 15.2487C15.0959 15.4015 14.9015 15.4779 14.6654 15.4779C14.4293 15.4779 14.2348 15.4015 14.082 15.2487L9.9987 11.1654Z"
|
||||
fill="#969696"
|
||||
/>
|
||||
</G>
|
||||
</Svg>
|
||||
</View>
|
||||
<Pressable
|
||||
onPress={hideBottomSheet}
|
||||
style={[GenericStyles.alignItemsFlexEnd, GenericStyles.ph16]}
|
||||
>
|
||||
<CrossIcon_20 />
|
||||
</Pressable>
|
||||
)}
|
||||
setVisible={hideBottomSheet}
|
||||
>
|
||||
<View style={[GenericStyles.ph16]}>
|
||||
<View style={{ paddingHorizontal: 52 }}>
|
||||
<Text style={styles.headerTxt}>Connecting you with the customer...</Text>
|
||||
<Text style={styles.descriptionTxt}>
|
||||
You will receive a call from NAVI. Post this a call will go to{' '}
|
||||
<Text style={styles.name}>Abhinav</Text> on{' '}
|
||||
<Text style={styles.phoneNumber}>XXXXXX9544</Text>
|
||||
</Text>
|
||||
<View
|
||||
style={[
|
||||
GenericStyles.ph16,
|
||||
GenericStyles.pv24,
|
||||
GenericStyles.fill,
|
||||
GenericStyles.justifyContentSpaceBetween,
|
||||
]}
|
||||
>
|
||||
<View style={GenericStyles.alignCenter}>
|
||||
<ConnectingToCustomerIcon />
|
||||
<View style={{ paddingHorizontal: 52, paddingTop: 24 }}>
|
||||
<Text style={styles.headerTxt}>Connecting you with the customer...</Text>
|
||||
<Text style={styles.descriptionTxt}>
|
||||
You will receive a call from NAVI. Post this a call will go to{' '}
|
||||
<Text style={styles.name}>{customerName ?? '--'}</Text> on{' '}
|
||||
<Text style={styles.phoneNumber}>{callAttemptedOn ?? '--'}</Text>
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<Button title="Understood" onPress={() => {}} style={[GenericStyles.w100]} />
|
||||
<Button title="Understood" onPress={hideBottomSheet} style={[GenericStyles.w100]} />
|
||||
</View>
|
||||
</BottomSheetWrapper>
|
||||
);
|
||||
|
||||
@@ -9,10 +9,25 @@ import { StyleSheet, View } from 'react-native';
|
||||
import { getPhoneSourceString } from '@components/utlis/commonFunctions';
|
||||
import { ICallHistoryItem } from '../interfaces';
|
||||
import { convertSecondsToDuration, getCallTypeIcon } from '../utils';
|
||||
import { setCallAttemptedOn } from '@reducers/telephoneNumbersSlice';
|
||||
import { makeACallToCustomer } from '@actions/callRecordingActions';
|
||||
import { useAppDispatch, useAppSelector } from '@hooks';
|
||||
|
||||
const CallHistoryItem = (props: ICallHistoryItem) => {
|
||||
const { callHistory, isLastElement } = props;
|
||||
const { telephoneNumber, sources, callDuration, timestamp, callType } = callHistory || {};
|
||||
const { callHistory, isLastElement, caseId } = props;
|
||||
const { telephoneNumber, sources, callDuration, timestamp, callType, telephoneReferenceId } =
|
||||
callHistory || {};
|
||||
|
||||
const loanAccountNumber = useAppSelector(
|
||||
(state) => state?.allCases?.caseDetails?.[caseId]?.loanAccountNumber
|
||||
);
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const callCustomer = () => {
|
||||
dispatch(setCallAttemptedOn(telephoneNumber));
|
||||
dispatch(makeACallToCustomer({ referenceId: telephoneReferenceId, loanAccountNumber }));
|
||||
};
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={[GenericStyles.row, GenericStyles.w100]}>
|
||||
@@ -31,14 +46,7 @@ const CallHistoryItem = (props: ICallHistoryItem) => {
|
||||
GenericStyles.justifyContentSpaceBetween,
|
||||
]}
|
||||
>
|
||||
<IconButton
|
||||
style={{ height: 36, width: 36 }}
|
||||
icon={<CallIcon />}
|
||||
round
|
||||
onPress={() => {
|
||||
console.log('object');
|
||||
}}
|
||||
/>
|
||||
<IconButton style={styles.iconButton} icon={<CallIcon />} round onPress={callCustomer} />
|
||||
<Text style={styles.sources}>{convertSecondsToDuration(callDuration)}</Text>
|
||||
</View>
|
||||
</View>
|
||||
@@ -67,5 +75,9 @@ const styles = StyleSheet.create({
|
||||
color: COLORS.TEXT.GREY_4,
|
||||
marginTop: 4,
|
||||
},
|
||||
iconButton: {
|
||||
height: 36,
|
||||
width: 36,
|
||||
},
|
||||
});
|
||||
export default CallHistoryItem;
|
||||
|
||||
@@ -7,6 +7,7 @@ import CallHistoryItem from './CallHistoryItem';
|
||||
import { useAppDispatch, useAppSelector } from '@hooks';
|
||||
import { fetchCallHistory } from '@actions/fetchTelephoneNumber';
|
||||
import { ICallHistory } from '../interfaces';
|
||||
import NoCallLogsIcon from '@rn-ui-lib/icons/NoCallLogsIcon';
|
||||
|
||||
const CallHistory = (props: ICallHistory) => {
|
||||
const { caseId } = props;
|
||||
@@ -22,6 +23,7 @@ const CallHistory = (props: ICallHistory) => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
useEffect(() => {
|
||||
dispatch(fetchCallHistory({ loanAccountNumber, caseId, setLoading }));
|
||||
}, []);
|
||||
@@ -42,9 +44,15 @@ const CallHistory = (props: ICallHistory) => {
|
||||
if (!callHistoryDetails?.length)
|
||||
return (
|
||||
<View
|
||||
style={[GenericStyles.fill, GenericStyles.centerAlignedRow, GenericStyles.whiteBackground]}
|
||||
style={[
|
||||
GenericStyles.fill,
|
||||
GenericStyles.centerAlignedRow,
|
||||
GenericStyles.columnDirection,
|
||||
GenericStyles.whiteBackground,
|
||||
]}
|
||||
>
|
||||
<Text>No call logs exist yet.</Text>
|
||||
<NoCallLogsIcon />
|
||||
<Text style={GenericStyles.pt7}>No call logs exist</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -58,6 +66,7 @@ const CallHistory = (props: ICallHistory) => {
|
||||
<CallHistoryItem
|
||||
callHistory={callHistory}
|
||||
isLastElement={index === callHistoryDetails.length - 1}
|
||||
caseId={caseId}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
|
||||
@@ -5,9 +5,18 @@ import RenderIcons from '@screens/caseDetails/journeyStepper/RenderIcon';
|
||||
import React from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { IPhoneNumberItem } from '../interfaces';
|
||||
import { getPhoneSourceString } from '@components/utlis/commonFunctions';
|
||||
import { useAppSelector } from '@hooks';
|
||||
import { RootState } from '@store';
|
||||
|
||||
const PhoneNumberItem = (props: IPhoneNumberItem) => {
|
||||
const { number, sourceText } = props;
|
||||
const { phoneNumber, caseId } = props;
|
||||
const { number, sources, referenceId } = phoneNumber;
|
||||
|
||||
const sourceText = getPhoneSourceString(sources);
|
||||
|
||||
const telephoneReferenceId = useAppSelector((state: RootState) => state?.activeCall?.referenceId);
|
||||
|
||||
return (
|
||||
<View>
|
||||
<View style={[GenericStyles.borderTop, GenericStyles.w100]} />
|
||||
@@ -20,15 +29,17 @@ const PhoneNumberItem = (props: IPhoneNumberItem) => {
|
||||
]}
|
||||
>
|
||||
<View style={GenericStyles.flex50}>
|
||||
<View style={[GenericStyles.row, GenericStyles.alignCenter, GenericStyles.mb4]}>
|
||||
<View style={styles.activeCallCircle} />
|
||||
<Text style={styles.activeCall}>Active call</Text>
|
||||
</View>
|
||||
{telephoneReferenceId === referenceId ? (
|
||||
<View style={[GenericStyles.row, GenericStyles.alignCenter, GenericStyles.mb4]}>
|
||||
<View style={styles.activeCallCircle} />
|
||||
<Text style={styles.activeCall}>Active call</Text>
|
||||
</View>
|
||||
) : null}
|
||||
<Text style={styles.phoneNumber}>{number}</Text>
|
||||
<Text style={styles.sources}>{sourceText}</Text>
|
||||
</View>
|
||||
<View style={[GenericStyles.flex50, GenericStyles.alignItemsFlexEnd]}>
|
||||
<RenderIcons mobileNumber={number} />
|
||||
<RenderIcons mobileNumber={number} referenceId={referenceId} caseId={caseId} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -8,7 +8,6 @@ import {
|
||||
StyleSheet,
|
||||
View,
|
||||
} from 'react-native';
|
||||
import { getPhoneSourceString } from '@components/utlis/commonFunctions';
|
||||
import Text from '@rn-ui-lib/components/Text';
|
||||
import { GenericStyles } from '@rn-ui-lib/styles';
|
||||
import { COLORS } from '@rn-ui-lib/colors';
|
||||
@@ -26,6 +25,12 @@ const CustomerNumbers = (props: ICustomerNumbers) => {
|
||||
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
const isExternalAgent = useAppSelector((state: RootState) => state?.user?.isExternalAgent);
|
||||
const genuineCallCount = useAppSelector(
|
||||
(state: RootState) => state?.telephoneNumbers?.callActivity?.[caseId]?.genuineCallCount
|
||||
);
|
||||
const enableAllTheFeatures = useAppSelector(
|
||||
(state: RootState) => state?.telephoneNumbers?.callActivity?.[caseId]?.enableFeature
|
||||
);
|
||||
|
||||
const handleAddNewNumberCta = () => {
|
||||
navigateToScreen(CaseDetailStackEnum.ADD_NEW_NUMBER, { caseId: caseId });
|
||||
@@ -35,7 +40,7 @@ const CustomerNumbers = (props: ICustomerNumbers) => {
|
||||
refetchMobileNumbers(setIsRefreshing);
|
||||
};
|
||||
|
||||
const showCallDetailsNudge = !isExternalAgent; // TODO Exotel: Add condition here
|
||||
const showCallDetailsNudge = !isExternalAgent && enableAllTheFeatures; // TODO Exotel: Add condition here
|
||||
|
||||
if (loading)
|
||||
return (
|
||||
@@ -75,7 +80,7 @@ const CustomerNumbers = (props: ICustomerNumbers) => {
|
||||
]}
|
||||
>
|
||||
<Text style={styles.greyColor}>Call customer to enable all features</Text>
|
||||
<Text style={styles.greyColor}>0/2</Text>
|
||||
<Text style={styles.greyColor}>{genuineCallCount}/2</Text>
|
||||
</View>
|
||||
) : null}
|
||||
<Pressable
|
||||
@@ -91,8 +96,8 @@ const CustomerNumbers = (props: ICustomerNumbers) => {
|
||||
<AddNumberIcon />
|
||||
<Text style={styles.addNewNumberCta}>Add new number</Text>
|
||||
</Pressable>
|
||||
{mobileNumbers.map(({ number, sources }) => (
|
||||
<PhoneNumberItem number={number} sourceText={getPhoneSourceString(sources)} />
|
||||
{mobileNumbers.map((number) => (
|
||||
<PhoneNumberItem phoneNumber={number} caseId={caseId} />
|
||||
))}
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
@@ -33,7 +33,7 @@ const CallingFlow = (props: ICallingFlow) => {
|
||||
<CallHistory caseId={caseId} />
|
||||
)}
|
||||
</View>
|
||||
<ConnectingToCustomerBottomSheet />
|
||||
<ConnectingToCustomerBottomSheet caseId={caseId} />
|
||||
<CallCannotInitiateBottomSheet />
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { ITelephoneNumbers } from '@reducers/telephoneNumbersSlice';
|
||||
import { IPhoneSources } from '../interface';
|
||||
|
||||
export interface IPhoneNumberItem {
|
||||
number: string;
|
||||
sourceText: string;
|
||||
phoneNumber: ITelephoneNumbers;
|
||||
caseId: string;
|
||||
}
|
||||
|
||||
export interface ICallCustomer {
|
||||
route?: {
|
||||
params?: {
|
||||
caseId?: string;
|
||||
route: {
|
||||
params: {
|
||||
caseId: string;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -22,12 +23,14 @@ export enum CallType {
|
||||
export interface ICallHistoryItem {
|
||||
callHistory: {
|
||||
telephoneNumber: string;
|
||||
telephoneReferenceId: string;
|
||||
sources: IPhoneSources[];
|
||||
callDuration: number;
|
||||
timestamp: number;
|
||||
callType: CallType;
|
||||
};
|
||||
isLastElement: boolean;
|
||||
caseId: string;
|
||||
}
|
||||
|
||||
export interface ICallHistory {
|
||||
@@ -46,3 +49,24 @@ export enum CallCustomerTabs {
|
||||
export interface ICallingFlow {
|
||||
caseId: string;
|
||||
}
|
||||
|
||||
export enum IconType {
|
||||
WHATSAPP = 'WHATSAPP',
|
||||
CALL = 'CALL',
|
||||
COPY = 'COPY',
|
||||
}
|
||||
|
||||
export interface IRenderIcons {
|
||||
mobileNumber: string;
|
||||
referenceId: string;
|
||||
caseId: string;
|
||||
}
|
||||
|
||||
export enum PhoneStateType {
|
||||
IDLE = 'IDLE',
|
||||
UNKNOWN = 'UNKNOWN',
|
||||
}
|
||||
|
||||
export interface IConnectingToCustomerBottomSheet {
|
||||
caseId: string;
|
||||
}
|
||||
|
||||
@@ -1,52 +1,78 @@
|
||||
import React from 'react';
|
||||
import { Linking, TouchableOpacity, View } from 'react-native';
|
||||
import { Linking, StyleSheet, View } from 'react-native';
|
||||
import { GenericStyles } from '../../../../RN-UI-LIB/src/styles';
|
||||
import { WhatsAppText } from '../../../common/Constants';
|
||||
import { copyToClipboard } from '../../../components/utlis/commonFunctions';
|
||||
import { toast } from '../../../../RN-UI-LIB/src/components/toast';
|
||||
import { COLORS } from '../../../../RN-UI-LIB/src/styles/colors';
|
||||
import CopyIconFilled from '../../../assets/icons/CopyIconFilled';
|
||||
import WhatsAppIcon_20 from '../../../assets/icons/WhatsAppIcon_20';
|
||||
import { IconProps } from '../../../../RN-UI-LIB/src/Icons/types';
|
||||
import IconButton from '@rn-ui-lib/components/IconButton';
|
||||
import CallIcon from './CallIcon';
|
||||
import { useAppSelector } from '@hooks';
|
||||
import { useAppDispatch, useAppSelector } from '@hooks';
|
||||
import { RootState } from '@store';
|
||||
import PhoneStateModule from '@components/utlis/PhoneState';
|
||||
import { setCallCannotInitiateBottomSheet } from '@reducers/activeCallSlice';
|
||||
import { logError } from '@components/utlis/errorUtils';
|
||||
import { makeACallToCustomer } from '@actions/callRecordingActions';
|
||||
import { IRenderIcons, IconType, PhoneStateType } from '../CallingFlow/interfaces';
|
||||
import { setCallAttemptedOn } from '@reducers/telephoneNumbersSlice';
|
||||
|
||||
const Icons = {
|
||||
WHATSAPP: WhatsAppIcon_20,
|
||||
COPY: CopyIconFilled,
|
||||
CALL: CallIcon,
|
||||
};
|
||||
const Actions = [
|
||||
{
|
||||
id: 1,
|
||||
icon: <WhatsAppIcon_20 />,
|
||||
type: IconType.WHATSAPP,
|
||||
},
|
||||
|
||||
enum IconType {
|
||||
WHATSAPP = 'WHATSAPP',
|
||||
CALL = 'CALL',
|
||||
COPY = 'COPY',
|
||||
}
|
||||
{
|
||||
id: 2,
|
||||
icon: <CopyIconFilled />,
|
||||
type: IconType.COPY,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
icon: <CallIcon />,
|
||||
type: IconType.CALL,
|
||||
},
|
||||
];
|
||||
|
||||
interface IRenderIcons {
|
||||
mobileNumber: string;
|
||||
closeSheet?: () => void;
|
||||
}
|
||||
const RenderIcons: React.FC<IRenderIcons> = ({ mobileNumber, closeSheet }) => {
|
||||
const lengthOfArray = Object.keys(Icons).length;
|
||||
const RenderIcons: React.FC<IRenderIcons> = ({ mobileNumber, referenceId, caseId }) => {
|
||||
const loanAccountNumber = useAppSelector(
|
||||
(state) => state?.allCases?.caseDetails?.[caseId]?.loanAccountNumber
|
||||
);
|
||||
const enableAllTheFeatures = useAppSelector(
|
||||
(state: RootState) => state?.telephoneNumbers?.callActivity?.[caseId]?.enableFeature
|
||||
);
|
||||
const lengthOfArray = Actions.length;
|
||||
const isExternalAgent = useAppSelector((state: RootState) => state?.user?.isExternalAgent);
|
||||
|
||||
const handleIconPress = (mobileNumber: string, icon: React.FC<IconProps>) => {
|
||||
switch (icon) {
|
||||
case Icons.CALL:
|
||||
if(isExternalAgent) {
|
||||
const dispatch = useAppDispatch();
|
||||
const handleIconPress = (actionType: IconType) => {
|
||||
switch (actionType) {
|
||||
case IconType.CALL:
|
||||
if (isExternalAgent) {
|
||||
Linking.openURL(`tel:${mobileNumber}`);
|
||||
} else {
|
||||
// TODO Exotel: Call API to connect the call
|
||||
return;
|
||||
}
|
||||
PhoneStateModule.getCurrentCallState()
|
||||
.then((callState: string) => {
|
||||
if (callState === PhoneStateType.IDLE || callState === PhoneStateType.UNKNOWN) {
|
||||
dispatch(setCallAttemptedOn(mobileNumber))
|
||||
dispatch(makeACallToCustomer({ referenceId, loanAccountNumber }));
|
||||
} else {
|
||||
dispatch(setCallCannotInitiateBottomSheet(true));
|
||||
}
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
logError(error, 'Error in getting call state');
|
||||
});
|
||||
|
||||
break;
|
||||
case Icons.WHATSAPP:
|
||||
case IconType.WHATSAPP:
|
||||
const phoneNumber = mobileNumber?.startsWith('+91') ? mobileNumber : `+91${mobileNumber}`;
|
||||
Linking.openURL(`whatsapp://send?phone=${phoneNumber}&text=${WhatsAppText}`);
|
||||
break;
|
||||
case Icons.COPY:
|
||||
case IconType.COPY:
|
||||
copyToClipboard(mobileNumber);
|
||||
toast({
|
||||
text1: 'Phone Number Copied',
|
||||
@@ -54,53 +80,26 @@ const RenderIcons: React.FC<IRenderIcons> = ({ mobileNumber, closeSheet }) => {
|
||||
});
|
||||
break;
|
||||
}
|
||||
closeSheet?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={[GenericStyles.centerAlignedRow]}>
|
||||
{Object.values(Icons).map((Icon, index) => {
|
||||
{Actions?.map((actionDetails, index) => {
|
||||
return (
|
||||
// <TouchableOpacity
|
||||
// key={index}
|
||||
// style={[
|
||||
// index !== 0 ? GenericStyles.ml10 : null,
|
||||
// index !== lengthOfArray - 1 ? GenericStyles.mr10 : null,
|
||||
// GenericStyles.p8,
|
||||
// GenericStyles.border,
|
||||
// {borderRadius: 50},
|
||||
// GenericStyles.centerAligned,
|
||||
// {
|
||||
// height: 36,
|
||||
// width: 36,
|
||||
// },
|
||||
// ]}
|
||||
// onPress={() => {
|
||||
// handleIconPress(mobileNumber, Icon);
|
||||
// }}
|
||||
// >
|
||||
// <View>
|
||||
// <Icon size={14} fillColor={COLORS.BASE.BLUE} />
|
||||
// </View>
|
||||
// </TouchableOpacity>
|
||||
<IconButton
|
||||
style={[
|
||||
index !== 0 ? GenericStyles.ml10 : null,
|
||||
index !== lengthOfArray - 1 ? GenericStyles.mr10 : null,
|
||||
GenericStyles.p8,
|
||||
GenericStyles.border,
|
||||
{ borderRadius: 50 },
|
||||
GenericStyles.centerAligned,
|
||||
{
|
||||
height: 36,
|
||||
width: 36,
|
||||
},
|
||||
styles.iconContainer,
|
||||
]}
|
||||
onPress={() => {
|
||||
handleIconPress(mobileNumber, Icon);
|
||||
handleIconPress(actionDetails?.type);
|
||||
}}
|
||||
disabled
|
||||
icon={<Icon size={20} fillColor={COLORS.BASE.BLUE} />}
|
||||
disabled={actionDetails?.type !== IconType.CALL ? !enableAllTheFeatures : false}
|
||||
icon={actionDetails?.icon}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
@@ -108,4 +107,12 @@ const RenderIcons: React.FC<IRenderIcons> = ({ mobileNumber, closeSheet }) => {
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
iconContainer: {
|
||||
borderRadius: 50,
|
||||
height: 36,
|
||||
width: 36,
|
||||
},
|
||||
});
|
||||
|
||||
export default RenderIcons;
|
||||
|
||||
@@ -10,9 +10,9 @@ import React from 'react';
|
||||
import { Pressable, StyleSheet, View } from 'react-native';
|
||||
|
||||
const CallInfo = () => {
|
||||
const phoneNumber = useAppSelector((state: RootState) => state.activeCall.phoneNumber);
|
||||
const customerName = useAppSelector((state: RootState) => state.activeCall.customerName);
|
||||
const caseId = useAppSelector((state: RootState) => state.activeCall.caseId);
|
||||
const phoneNumber = useAppSelector((state: RootState) => state?.activeCall?.phoneNumber);
|
||||
const customerName = useAppSelector((state: RootState) => state?.activeCall?.customerName);
|
||||
const caseId = useAppSelector((state: RootState) => state?.activeCall?.caseId);
|
||||
|
||||
const onPressHandler = () => {
|
||||
navigateToScreen(PageRouteEnum.CASE_DETAIL_STACK, {
|
||||
|
||||
@@ -7,7 +7,7 @@ const Layout: React.FC<PropsWithChildren> = (props) => {
|
||||
return (
|
||||
<>
|
||||
<Offline />
|
||||
<CallInfo />
|
||||
{/* <CallInfo /> */}
|
||||
{props.children}
|
||||
</>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user