* add new screeen for new number TP-22456

* add UI for Add new Number screen TP-22456

* numeric keyboard and event name fixes TP-22456

* add api helper TP-22456

* add api TP-22456

* api helpers tested TP-22456
This commit is contained in:
Aman Sethi
2023-03-30 15:42:20 +05:30
committed by GitHub Enterprise
parent f1f4f82515
commit e267f0940a
10 changed files with 324 additions and 12 deletions

View File

@@ -34,6 +34,7 @@ import { getCaseUnifiedData, UnifiedCaseDetailsTypes } from './src/action/caseAp
import FeedbackDetailContainer from './src/screens/caseDetails/feedback/FeedbackDetailContainer';
import EmiSchedule from './src/screens/emiSchedule';
import { NetworkStatusService } from "./src/services/network-monitoring.service";
import AddNewNumber from './src/screens/addNewNumber';
const ANIMATION_DURATION = 300;
@@ -264,6 +265,16 @@ const ProtectedRouter = () => {
}}
listeners={getScreenFocusListenerObj}
/>
<Stack.Screen
name="AddNewNumber"
component={AddNewNumber}
options={{
header: () => null,
animation: 'slide_from_right',
animationDuration: ANIMATION_DURATION,
}}
listeners={getScreenFocusListenerObj}
/>
</>
) : (
<>

View File

@@ -352,7 +352,7 @@ const allCasesSlice = createSlice({
if (newVisitCaseLoanIds?.length > 0) {
addClickstreamEvent(
CLICKSTREAM_EVENT_NAMES.FIELD_APP_CASES_PINNED_UPDATED,
CLICKSTREAM_EVENT_NAMES.FA_VISIT_PLAN_UPDATED,
{
newPinCases: [...newVisitCaseLoanIds],
currentPinCases: pinnedList.map(item =>
@@ -372,7 +372,7 @@ const allCasesSlice = createSlice({
}
if(removedVisitedCasesLoanIds.length > 0) {
addClickstreamEvent(
CLICKSTREAM_EVENT_NAMES.FIELD_APP_CASES_PINNED_UPDATED,
CLICKSTREAM_EVENT_NAMES.FA_VISIT_PLAN_UPDATED,
{
newUnpinCases: [...removedVisitedCasesLoanIds],
currentPinCases: pinnedList.map(item =>

View File

@@ -0,0 +1,52 @@
import { AxiosResponse } from 'axios';
import { PageRouteEnum } from '../../../ProtectedRouter';
import { toast } from '../../../RN-UI-LIB/src/components/toast';
import { GenericFunctionArgs } from '../../common/GenericTypes';
import axiosInstance from '../../components/utlis/apiHelper';
import { navigateToScreen } from '../../components/utlis/navigationUtlis';
import { Source, Tag } from './const';
interface IAddNewNumberApi {
tag: Tag;
source: Source;
number: string;
customerReferenceId: string;
caseId: string;
}
export const addNewNumberApi = (
data: IAddNewNumberApi,
afterApiCallback?: GenericFunctionArgs,
) => {
const { tag, source, number, customerReferenceId, caseId } = data;
const url = '/telephones';
const payload = [
{
number,
tag,
origin: source,
},
];
axiosInstance
.post(url, payload, {
params: {
customerReferenceId,
},
})
.then((response: AxiosResponse) => {
if (response.status === 200) {
toast({
type: 'info',
text1: 'Number added successfully',
});
navigateToScreen(PageRouteEnum.COLLECTION_CASE_DETAIL, {
caseId: caseId,
});
}
})
.catch(error => {
return error?.response?.data || error?.message || error;
})
.finally(() => {
afterApiCallback && afterApiCallback();
});
};

View File

@@ -0,0 +1,12 @@
export enum Tag {
Customer = 'Customer',
Relative = 'Relative',
Others = 'Others',
}
export enum Source {
Relative = 'Relative',
Neighbour = 'Neighbour',
Security = 'Security',
Others = 'Others',
}

View File

@@ -0,0 +1,233 @@
import { SafeAreaView, View, StyleSheet } from 'react-native';
import React, { useState } from 'react';
import Text from '../../../RN-UI-LIB/src/components/Text';
import Layout from '../layout/Layout';
import NavigationHeader, {
Icon,
} from '../../../RN-UI-LIB/src/components/NavigationHeader';
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 { Controller, useForm } from 'react-hook-form';
import { Source, Tag } from './const';
import DropdownItem from '../registerPayements/DropdownItem';
import { getDynamicBottomSheetHeightPercentageFn } from '../../components/utlis/commonFunctions';
import { addNewNumberApi } from './apiHelper';
import { useAppSelector } from '../../hooks';
interface IAddNewNumber {
number: string;
source: Source;
tag: Tag;
}
const HEADER_HEIGHT = 100;
const ROW_HEIGHT = 40;
interface IAddNewNumber {
route: {
params: {
caseId: string;
};
};
}
const AddNewNumber: React.FC<IAddNewNumber> = props => {
const [loading, setLoading] = useState(false);
const { caseId } = props.route.params;
const { customerReferenceId } = useAppSelector(
state => state.allCases.caseDetails[caseId],
);
const {
control,
getValues,
formState: { isValid, defaultValues, errors },
trigger,
} = useForm<IAddNewNumber>({
defaultValues: {
number: '',
source: undefined,
tag: undefined,
},
mode: 'onChange',
});
const onBack = () => {
popToScreen(1);
};
const SourceChildComponents = Object.values(Source).map(source => {
return <DropdownItem createdAt={source} id={source} label={source} />;
});
const TagChildComponents = Object.values(Tag).map(tag => {
return <DropdownItem createdAt={tag} id={tag} label={tag} />;
});
const getBottomSheetHeight = getDynamicBottomSheetHeightPercentageFn(
HEADER_HEIGHT,
ROW_HEIGHT,
);
const addCtaHandler = () => {
setLoading(true);
addNewNumberApi(
{
customerReferenceId: customerReferenceId,
...getValues(),
caseId,
},
() => {
setLoading(false);
},
);
};
return (
<Layout>
<SafeAreaView
style={[
GenericStyles.whiteBackground,
{
height: '100%',
},
]}>
<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 },
}) => (
<Dropdown
placeholder="Select"
onValueChange={number => {
onChange(number);
trigger();
}}
bottomSheetHeight={getBottomSheetHeight(
Object.values(Source).length,
)}
header="Source of the number"
value={value ?? ''}>
{SourceChildComponents}
</Dropdown>
)}
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 },
}) => (
<Dropdown
placeholder="Select"
onValueChange={number => {
onChange(number);
trigger();
}}
bottomSheetHeight={getBottomSheetHeight(
Object.values(Tag).length,
)}
header="Tag number"
value={value ?? ''}>
{TagChildComponents}
</Dropdown>
)}
name="tag"
rules={{ required: true }}
/>
</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>
</SafeAreaView>
</Layout>
);
};
const styles = StyleSheet.create({
shadowContainer: {
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 4,
},
shadowOpacity: 0.08,
shadowRadius: 20,
borderRadius: 8,
},
buttonContainer: {
bottom: 24,
position: 'absolute',
},
});
export default AddNewNumber;

View File

@@ -83,7 +83,7 @@ export const CasesActionButtons: React.FC = () => {
return updatedCaseItem;
});
addClickstreamEvent(
CLICKSTREAM_EVENT_NAMES.FIELD_APP_CASES_UNPINNED_CTA,
CLICKSTREAM_EVENT_NAMES.FA_REMOVE_FROM_VISIT_PLAN_CTA,
{
newUnpinCases: [...newlyUnpinnedCaseLoanIds],
currentPinCases: pinnedList.map(item =>

View File

@@ -153,6 +153,11 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = props => {
setShowPhoneNumberSheet(true);
};
const handleAddNewNumberCta = () => {
navigateToScreen('AddNewNumber', { caseId: caseId });
setShowPhoneNumberSheet(false);
};
const handleAddFeedback = () => {
if (data?.visitedWidgets?.length) {
_map(data.visitedWidgets, visited =>
@@ -517,6 +522,7 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = props => {
setSelectedPhoneNumber={setSelectedPhoneNumber}
mobileNumbers={phoneNumbers ?? []}
setShowPhoneNumberBottomSheet={setShowPhoneNumberSheet}
handleAddNewNumberCta={handleAddNewNumberCta}
/>
<CallingBottomSheet
setShowCallingBottomSheet={setShowCallingBottomSheet}

View File

@@ -11,6 +11,8 @@ import CallIcon from '../../../../RN-UI-LIB/src/Icons/CallIcon';
import { PhoneNumber } from '../interface';
import { SourceTextFocused } from '../../../common/Constants';
import { getDynamicBottomSheetHeightPercentageFn } from '../../../components/utlis/commonFunctions';
import Button from '../../../../RN-UI-LIB/src/components/Button';
import { navigateToScreen } from '../../../components/utlis/navigationUtlis';
interface PhoneNumberSelectionBottomSheetProps {
showPhoneNumberBottomSheet: boolean;
@@ -21,6 +23,7 @@ interface PhoneNumberSelectionBottomSheetProps {
setShowCallingBottomSheet: React.Dispatch<React.SetStateAction<boolean>>;
selectedPhoneNumber: string;
setSelectedPhoneNumber: React.Dispatch<React.SetStateAction<string>>;
handleAddNewNumberCta: () => void;
}
const PhoneNumberSelectionBottomSheet: React.FC<
@@ -33,6 +36,7 @@ const PhoneNumberSelectionBottomSheet: React.FC<
setShowCallingBottomSheet,
selectedPhoneNumber,
setSelectedPhoneNumber,
handleAddNewNumberCta,
} = props;
const getBottomSheetHeight = getDynamicBottomSheetHeightPercentageFn();
@@ -52,13 +56,7 @@ const PhoneNumberSelectionBottomSheet: React.FC<
<Heading dark type="h4">
Select number to call
</Heading>
<TouchableOpacity
activeOpacity={0.7}
onPress={() =>
setShowPhoneNumberBottomSheet(prev => !prev)
}>
<CloseIcon color={COLORS.TEXT.LIGHT} />
</TouchableOpacity>
<Button title='Add new number' onPress={handleAddNewNumberCta} variant='primaryText' buttonStyle={{padding: 0}} />
</View>
)}
setVisible={() => setShowPhoneNumberBottomSheet(prev => !prev)}>

View File

@@ -11,7 +11,7 @@ export interface IDropdownItem {
label: string;
close?: () => void;
handleSelection?: (id: string) => void;
sourceText: string;
sourceText?: string;
}
const DropdownItem: React.FC<IDropdownItem> = ({

View File

@@ -99,7 +99,7 @@ const TodoList = () => {
},
);
addClickstreamEvent(
CLICKSTREAM_EVENT_NAMES.FIELD_APP_CASES_PINNED_CTA,
CLICKSTREAM_EVENT_NAMES.FA_ADD_TO_VISIT_PLAN_CTA,
{
newPinCases: [...newPinedCasesLoanAccountNumbers],
currentPinCases: pinnedList.map(item =>