TP-77706 docs fix (#907)

This commit is contained in:
Mantri Ramkishor
2024-08-29 17:35:35 +05:30
committed by GitHub
12 changed files with 149 additions and 161 deletions

View File

@@ -14,6 +14,7 @@ import {
getPrefixBase64Image,
LocalStorageKeys,
MimeType,
NAVI_AGENCY_CODE,
} from '../../common/Constants';
import NetInfo from '@react-native-community/netinfo';
import Clipboard from '@react-native-clipboard/clipboard';
@@ -590,3 +591,7 @@ export const handleDownloadPdfDocument = async (document: IDocumentItem | IDocum
logError(error as Error);
});
};
export const checkExternalAgency = (agencyName: string, agencyCode: string) => {
return (agencyName && agencyCode !== NAVI_AGENCY_CODE);
}

View File

@@ -1,14 +1,10 @@
import { Pressable, SafeAreaView, StyleSheet, View } from 'react-native';
import React, { useEffect, useMemo, useState } from 'react';
import NaviLogoWithTextIcon from '../../../RN-UI-LIB/src/Icons/NaviLogoWithTextIcon';
import Avatar from '../../../RN-UI-LIB/src/components/Avatar';
import { GenericStyles } from '../../../RN-UI-LIB/src/styles';
import Text from '../../../RN-UI-LIB/src/components/Text';
import Heading from '../../../RN-UI-LIB/src/components/Heading';
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
import { useAppDispatch, useAppSelector } from '../../hooks';
import { BUSINESS_DATE_FORMAT, dateFormat } from '../../../RN-UI-LIB/src/utlis/dates';
import { NAVI_AGENCY_CODE } from '../../common/Constants';
import Layout from '@screens/layout/Layout';
import NavigationHeader from '@rn-ui-lib/components/NavigationHeader';
import { goBack, popToScreen } from '@components/utlis/navigationUtlis';
@@ -19,6 +15,8 @@ import RetryIcon from '@assets/icons/RetryIcon';
import ScreenshotBlocker from '@components/utlis/ScreenshotBlocker';
import { getSelfieDocument } from '@actions/profileActions';
import { setShouldHideTabBar } from '@reducers/commonSlice';
import AgentIdCardDetails from './AgentIdCardDetails';
import { checkExternalAgency } from '@components/utlis/commonFunctions';
const PAGE_TITLE = 'Agent ID card';
@@ -72,32 +70,19 @@ const AgentIdCard = () => {
const {
originalImageUri,
optimizedImageUri,
agentName,
agentPhone,
agencyName,
agentEmail,
agencyCode,
employeeId,
} = useAppSelector((state) => ({
originalImageUri: state.profile.originalImageUri,
agentName: state.user.user?.name!!,
agentPhone: state.user.user?.phoneNumber,
agencyName: state.profile.agencyName,
agentEmail: state.user.user?.emailId,
agencyCode: state.profile.agencyCode,
employeeId: state.user?.employeeId,
optimizedImageUri: state.profile.optimizedImageUri,
}));
const originalImageUri = useAppSelector((state) => state.profile.originalImageUri);
const optimizedImageUri = useAppSelector((state) => state.profile.optimizedImageUri);
const agentName = useAppSelector((state) => state.user.user?.name!!);
const agencyName = useAppSelector((state) => state.profile?.agencyName);
const agencyCode = useAppSelector((state) => state.profile?.agencyCode);
const showRetry = useMemo(() => {
return !originalImageUri && !optimizedImageUri;
}, [optimizedImageUri, originalImageUri]);
const isExternalAgency = (agencyName && agencyCode !== NAVI_AGENCY_CODE);
const isExternalAgency = useMemo(() => checkExternalAgency(agencyName, agencyCode), [agencyName, agencyCode]);
const loaderConf = useMemo(()=>{
return [
@@ -110,9 +95,6 @@ const AgentIdCard = () => {
]
},[])
return (
<Layout>
<SafeAreaView>
@@ -154,50 +136,9 @@ const AgentIdCard = () => {
)) || null}
</>
) : (
<>
<NaviLogoWithTextIcon />
{isExternalAgency ? (
<>
<Text small bold style={styles.greyColor}>
in association with
</Text>
<Text dark bold>
{agencyName}
</Text>
</>
) : null}
<Text style={styles.greyColor}>
Valid as of {dateFormat(new Date(todaysDate), BUSINESS_DATE_FORMAT)}
</Text>
<View style={styles.avatarMargin}>
<Text style={styles.greyColor}>
{'Debt Management Executive'}
</Text>
<Heading type="h4" dark bold style={GenericStyles.mv4}>
{agentName}
</Heading>
<View style={styles.flexContainer}>
<Text style={styles.greyColor}>
{agentEmail}
</Text>
<Text style={styles.greyColor}>
{' | '}
</Text>
<Text style={styles.greyColor}>
{agentPhone}
</Text>
</View>
{employeeId ? <View style={styles.flexContainer}>
<Text style={styles.darkBlueColor}>
{'Emp ID '}
</Text>
<Text style={styles.greyColor}>
{employeeId}
</Text>
</View> : null}
</View>
</>
<AgentIdCardDetails
todaysDate={todaysDate}
/>
)}
</View>
</SafeAreaView>
@@ -214,16 +155,8 @@ const styles = StyleSheet.create({
borderWidth: 3,
borderColor: COLORS.BORDER.PRIMARY,
},
flexContainer : {
display:'flex',
flexDirection:'row',
},
greyColor: {
color: COLORS.TEXT.GREY,
},
darkBlueColor: {
color: COLORS.TEXT.DARK_BLUE,
},
lineLoader: {
borderRadius: 20,
},
@@ -233,10 +166,6 @@ const styles = StyleSheet.create({
mt70: {
marginTop: 70,
},
avatarMargin: {
alignItems: 'center',
marginTop: 310,
},
retryContainer: {
marginTop: 30,
},

View File

@@ -0,0 +1,84 @@
import { checkExternalAgency } from '@components/utlis/commonFunctions';
import { useAppSelector } from '@hooks';
import { COLORS } from '@rn-ui-lib/colors';
import Heading from '@rn-ui-lib/components/Heading';
import Text from '@rn-ui-lib/components/Text';
import NaviLogoWithTextIcon from '@rn-ui-lib/icons/NaviLogoWithTextIcon';
import { GenericStyles } from '@rn-ui-lib/styles';
import { BUSINESS_DATE_FORMAT, dateFormat } from '@rn-ui-lib/utils/dates';
import { useMemo } from 'react';
import { View } from 'react-native';
import { StyleSheet } from 'react-native';
interface IAgentCardDetails {
todaysDate: Date;
}
const AgentIdCardDetails = ({
todaysDate,
}: IAgentCardDetails) => {
const agentName = useAppSelector((state) => state.user.user?.name!!);
const agentPhone = useAppSelector((state) => state.user.user?.phoneNumber);
const agencyName = useAppSelector((state) => state.profile?.agencyName);
const agentEmail = useAppSelector((state) => state.user.user?.emailId);
const agencyCode = useAppSelector((state) => state.profile?.agencyCode);
const employeeId = useAppSelector((state) => state.user?.employeeId);
const isExternalAgency = useMemo(() => checkExternalAgency(agencyName, agencyCode), [agencyName, agencyCode]);
return (
<>
<NaviLogoWithTextIcon />
{isExternalAgency ? (
<>
<Text small bold style={styles.greyColor}>
in association with
</Text>
<Text dark bold>
{agencyName}
</Text>
</>
) : null}
<Text style={styles.greyColor}>
Valid as of {dateFormat(new Date(todaysDate), BUSINESS_DATE_FORMAT)}
</Text>
<View style={styles.avatarMargin}>
<Text style={styles.greyColor}>{'Debt Management Executive'}</Text>
<Heading type="h4" dark bold style={GenericStyles.mv4}>
{agentName}
</Heading>
<View style={styles.flexContainer}>
<Text style={styles.greyColor}>{agentEmail}</Text>
<Text style={styles.greyColor}>{' | '}</Text>
<Text style={styles.greyColor}>{agentPhone}</Text>
</View>
{employeeId ? (
<View style={styles.flexContainer}>
<Text style={styles.darkBlueColor}>{'Emp ID '}</Text>
<Text style={styles.greyColor}>{employeeId}</Text>
</View>
) : null}
</View>
</>
);
};
export default AgentIdCardDetails;
const styles = StyleSheet.create({
flexContainer: {
display: 'flex',
flexDirection: 'row',
},
greyColor: {
color: COLORS.TEXT.GREY,
},
darkBlueColor: {
color: COLORS.TEXT.DARK_BLUE,
},
avatarMargin: {
alignItems: 'center',
marginTop: 310,
},
});

View File

@@ -1,5 +1,5 @@
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
import { getDistanceFromLatLonInKm } from '@components/utlis/commonFunctions';
import { getDistanceFromLatLonInKm, isFunction } from '@components/utlis/commonFunctions';
import { IGeoLocation } from '@interfaces/addressGeolocation.types';
import { addClickstreamEvent } from '@services/clickstreamEventService';
import {
@@ -223,9 +223,12 @@ export const updateNearbyCasesListAndLocation = (
return;
};
export const getCustomerDocuments = async (loanAccountNumber: string) =>
{
export const getCustomerDocuments = async (
loanAccountNumber: string,
setIsDocumentsLoading?: (val: boolean) => void
) => {
if (!loanAccountNumber) return;
isFunction(setIsDocumentsLoading) && setIsDocumentsLoading(true);
const url = getApiUrl(ApiKeys.FETCH_CUSTOMER_DOCUMENTS, { loanAccountNumber });
await axiosInstance
.get(url)
@@ -247,6 +250,9 @@ export const getCustomerDocuments = async (loanAccountNumber: string) =>
})
.catch((err) => {
logError(err);
})
.finally(() => {
isFunction(setIsDocumentsLoading) && setIsDocumentsLoading(false);
});
};

View File

@@ -61,17 +61,6 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = (props) => {
};
}, [caseId]);
const fetchCustomerDocuments = (loanAccountNumber: string) => {
setIsDocumentsLoading(true);
try {
getCustomerDocuments(loanAccountNumber);
} catch (error: GenericType) {
logError(error as Error);
} finally {
setIsDocumentsLoading(false);
}
};
useEffect(() => {
if (!loanAccountNumber) {
return;
@@ -83,7 +72,6 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = (props) => {
[UnifiedCaseDetailsTypes.FEEDBACKS, UnifiedCaseDetailsTypes.ADDRESS_AND_GEOLOCATIONS]
)
);
fetchCustomerDocuments(loanAccountNumber);
}
}, [caseDetail]);
@@ -126,7 +114,7 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = (props) => {
<SafeAreaView style={[GenericStyles.fill, GenericStyles.whiteBackground]}>
<ScrollView style={styles.contentContainer} stickyHeaderIndices={[0]}>
<CaseDetailsHeader caseDetail={caseDetail} />
<UserDetailsSection caseDetail={caseDetail} isDocumentsLoading={isDocumentsLoading}/>
<UserDetailsSection caseDetail={caseDetail} isDocumentsLoading={isDocumentsLoading} />
<Animated.View
style={[
{ opacity: opacityAnimation },

View File

@@ -11,7 +11,7 @@ import { SafeAreaView } from 'react-native-safe-area-context';
import { GenericStyles, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles';
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
import NavigationHeader, { Icon } from '../../../RN-UI-LIB/src/components/NavigationHeader';
import { CaseDetail, DocumentDetail, DOCUMENT_TYPE, IDocument } from './interface';
import { CaseDetail, DOCUMENT_TYPE } from './interface';
import useIsOnline from '../../hooks/useIsOnline';
import useFetchDocument from '../../hooks/useFetchDocument';
import {
@@ -22,8 +22,7 @@ import {
import { goBack } from '../../components/utlis/navigationUtlis';
import ScreenshotBlocker from '../../components/utlis/ScreenshotBlocker';
import { useIsFocused } from '@react-navigation/native';
import DocumentDetails from './DocumentDetails';
import { getCachedImageBase64, getDocumentDetails } from './utils/documentUtils';
import { getCachedImageBase64 } from './utils/documentUtils';
import CachedImage from '../../common/CachedImage';
import ImagePlaceholderError from '../../assets/icons/ImagePlaceholderError';
import RetryIcon from '../../assets/icons/RetryIcon';
@@ -31,18 +30,18 @@ import FastImage from 'react-native-fast-image';
import { useTimeout } from 'react-native-toast-message/lib/src/hooks';
import { CLICKSTREAM_EVENT_NAMES, DELAY_FOR_PAINTING_IMAGE } from '../../common/Constants';
import Text from '../../../RN-UI-LIB/src/components/Text';
import { isNullOrEmptyString } from '../../../RN-UI-LIB/src/utlis/common';
import { CUSTOMER_PROFILE_DOCS } from './constants';
import { isNullOrEmptyString, noop } from '../../../RN-UI-LIB/src/utlis/common';
import DocumentTabs from './DocumentTabs';
import { addClickstreamEvent } from '@services/clickstreamEventService';
import { useAppSelector } from '@hooks';
import { CUSTOMER_PROFILE_IMAGE } from '@constants/Global';
import useMobileNumbers from '@hooks/useMobileNumbers';
import { getCustomerDocuments } from '@screens/allCases/utils';
interface ICustomerProfile {
route: {
params: {
caseDetail: CaseDetail;
isDocumentsLoading: boolean;
};
};
}
@@ -50,7 +49,7 @@ interface ICustomerProfile {
const CustomerProfile: React.FC<ICustomerProfile> = (props) => {
const {
route: {
params: { caseDetail, isDocumentsLoading },
params: { caseDetail },
},
} = props;
const [errorModalImage, setErrorModalImage] = useState<boolean>(false);
@@ -58,10 +57,13 @@ const CustomerProfile: React.FC<ICustomerProfile> = (props) => {
const [retry, setRetry] = useState(true);
const [errorCount, setErrorCount] = useState<number>(0);
const [isHighQualityImageLoaded, setIsHighQualityImageLoaded] = useState(false);
const [documentsLoading, setDocumentsLoading] = useState(false);
const [showLoadingState, setShowLoadingState] = useState(false);
const [isDocumentsLoading, setIsDocumentsLoading] = React.useState(false);
const agentId = useAppSelector((state) => state?.user?.user?.referenceId);
const documentsData = useAppSelector((state) => state?.documentsSlice?.documentsData);
const loanAccountNumber = caseDetail?.loanAccountNumber;
const { startTimer, isActive, clearTimer } = useTimeout(() => {
setLoading(false);
}, DELAY_FOR_PAINTING_IMAGE);
@@ -77,7 +79,6 @@ const CustomerProfile: React.FC<ICustomerProfile> = (props) => {
false,
false
);
const [documentData, setDocumentData] = useState<Array<DocumentDetail>>([]);
const getImageURI = () => {
if (!isOnline) {
@@ -94,29 +95,16 @@ const CustomerProfile: React.FC<ICustomerProfile> = (props) => {
);
};
const { mobileNumbers } = useMobileNumbers(caseDetail?.caseReferenceId);
useEffect(() => {
if (caseDetail) {
setDocumentsLoading(true);
const docList: IDocument[] = getDocumentList(caseDetail) || [];
const docPromises: Promise<DocumentDetail | null>[] = [];
CUSTOMER_PROFILE_DOCS.forEach((documentType) => {
const document = findDocumentByDocumentType(docList, documentType);
if (document) {
const docPromise = getDocumentDetails(document);
if (docPromise) docPromises.push(docPromise);
}
});
Promise.all(docPromises)
.then((docs: Array<DocumentDetail | null>) => {
const documents = docs?.filter(
(document: DocumentDetail | null) => document
) as Array<DocumentDetail>;
setDocumentData(documents);
})
.catch(() => {})
.finally(() => setDocumentsLoading(false));
if (isOnline && loanAccountNumber) {
getCustomerDocuments(
loanAccountNumber,
documentsData?.[loanAccountNumber] ? noop : setIsDocumentsLoading
);
}
}, [caseDetail]);
}, []);
const onLoadStart = () => {
setLoading(true);

View File

@@ -57,8 +57,6 @@ const DocumentImageComponent = (props: DocumentImageComponentProps) => {
});
};
useS3UrlCheck(uri, documentRefId, caseId, caseType, unsignedUri, setImageUrl, setIsValidating);
return (
<>
<TouchableOpacity activeOpacity={1} onPress={handleExpandImage} testID="docImage">

View File

@@ -9,6 +9,7 @@ import { ActivityIndicator, StyleSheet } from 'react-native';
import { COLORS } from '@rn-ui-lib/colors';
import { addClickstreamEvent } from '@services/clickstreamEventService';
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
import { AGENT_TAB_KEY, AGENT_TAB_NAME } from './constants';
interface IDocumentTabs {
@@ -21,12 +22,12 @@ interface IDocumentTabs {
const DocumentTabs: React.FC<IDocumentTabs> = ({ lan, caseId, isDocumentsLoading, scrollByOffset }) => {
const documentsData = useAppSelector((state) => state?.documentsSlice?.documentsData);
const data = documentsData[lan];
const data = documentsData?.[lan];
const agentsData = useAppSelector((state) => state?.documentsSlice?.agentDocumentsData);
const [DOCUMENTS_TABS, SET_DOCUMENT_TABS] = useState<Tab[]>([]);
const [documentTabs, setDocumentTabs] = useState<Tab[]>([]);
const [documentsList, setDocumentsList] = useState<IDocumentItem[]>([]);
const [selectedTab, setSelectedTab] = useState<string>(DOCUMENTS_TABS?.[0]?.key || '');
const [selectedTab, setSelectedTab] = useState<string>(documentTabs?.[0]?.key || '');
useEffect(() => {
const docTabs: Tab[] = [];
@@ -50,10 +51,10 @@ const DocumentTabs: React.FC<IDocumentTabs> = ({ lan, caseId, isDocumentsLoading
agentsData &&
docTabs.push({
key: 'AGENT',
label: 'Agent',
key: AGENT_TAB_KEY,
label: AGENT_TAB_NAME,
});
SET_DOCUMENT_TABS(docTabs);
setDocumentTabs(docTabs);
if (agentsData) {
agentsData?.forEach((doc: IDocumentItem) => {
@@ -64,8 +65,8 @@ const DocumentTabs: React.FC<IDocumentTabs> = ({ lan, caseId, isDocumentsLoading
}, [data, agentsData]);
useEffect(() => {
setSelectedTab(DOCUMENTS_TABS?.[0]?.key || '');
}, [DOCUMENTS_TABS]);
setSelectedTab(documentTabs?.[0]?.key || '');
}, [documentTabs]);
const handleTabChange = (tabKey: string) => {
addClickstreamEvent(
@@ -89,7 +90,7 @@ const DocumentTabs: React.FC<IDocumentTabs> = ({ lan, caseId, isDocumentsLoading
) : (
<>
<CustomTabs
tabs={DOCUMENTS_TABS}
tabs={documentTabs}
currentTab={selectedTab}
onTabChange={handleTabChange}
containerStyle={[GenericStyles.ml20]}

View File

@@ -1,9 +1,7 @@
import React, { useEffect, useState } from 'react';
import {
ActivityIndicator,
Pressable,
SafeAreaView,
ScrollView,
StyleSheet,
View,
useWindowDimensions,
@@ -30,12 +28,10 @@ import { NAVI_ACCOUNT_SHARE_CHANNELS, ShareVia } from './constants';
import PDFScreenShareJourneyBottomSheet from './PDFScreenShareJourneyBottomSheet';
import { addClickstreamEvent } from '@services/clickstreamEventService';
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
import { ITelephoneNumbers } from '@reducers/telephoneNumbersSlice';
import useMobileNumbers from '@hooks/useMobileNumbers';
import { logError } from '@components/utlis/errorUtils';
import { GenericType } from '@common/GenericTypes';
import DownloadSolidIcon from '@rn-ui-lib/icons/DownloadSolidIcon';
import PDFDownload from './PDFDownload';
import { useAppSelector } from '@hooks';
interface IPdfFullScreen {
route: {
@@ -76,6 +72,9 @@ const PDFFullScreen: React.FC<IPdfFullScreen> = (props) => {
},
} = props;
const mobileNumbers =
useAppSelector((state) => state?.telephoneNumbers?.telephoneNumbers?.[caseId]) || [];
const [isLoading, setIsLoading] = useState<boolean>(false);
const [pdfFilePath, setPdfFilePath] = useState<string>('');
const [error, setError] = useState<boolean>(false);
@@ -89,8 +88,6 @@ const PDFFullScreen: React.FC<IPdfFullScreen> = (props) => {
return calculateBottomSheetHeight(mobileNumbers?.length || 0);
};
useS3UrlCheck(pdfUri, referenceId, caseId, caseType, unSignedUri, setPdfUrl, setIsValidating);
useEffect(() => {
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_PDF_VIEWER_OPENED, {
agentId: referenceId,
@@ -109,8 +106,6 @@ const PDFFullScreen: React.FC<IPdfFullScreen> = (props) => {
goBack();
};
const { mobileNumbers } = useMobileNumbers(caseId);
useEffect(() => {
setIsBottomSheetVisible(showShareBottomsheet && !isLoading && !error);
}, [showShareBottomsheet, isLoading, error]);

View File

@@ -50,9 +50,9 @@ export const ShareAndDownloadJourney = ({
isDownloadBottomSheetVisible,
setIsDownloadBottomSheetVisible,
}: IShareAndDownloadJourney) => {
const { agentId } = useAppSelector((state) => ({
agentId: state.user.user?.referenceId!,
}));
const agentId = useAppSelector((state) => state.user.user?.referenceId!);
const mobileNumbers =
useAppSelector((state) => state?.telephoneNumbers?.telephoneNumbers?.[caseId]) || [];
const { shareablePersonalAccount = false, languagesAvailable = [] } = document || {};
const getBottomSheetHeightCalculation = (
@@ -67,11 +67,6 @@ export const ShareAndDownloadJourney = ({
return calculateBottomSheetHeight(mobileNumbers?.length || 0);
};
const {mobileNumbers} = useMobileNumbers(caseId);
const fetchMultiLingualDocument = async (documentName: string, language: string) => {
try{
const multiLingualDoc = await getDocumentInSpecificLanguage(lan, documentName, language).then((res) => {

View File

@@ -121,6 +121,7 @@ export const ShareJourneyBottomSheet = ({
lan: loanAccountNumber,
agentId: agentId,
language: phoneNumberRefId,
document: documentKey,
})
handleSharePDF(document, ShareVia.NAVI_ACCOUNT, phoneNumberRefId);
resetBottomSheet();

View File

@@ -7,8 +7,6 @@ const VKYCVideo = ({ document, caseId, caseType }: any) => {
const { uri, unsignedUri, documentRefId } = document;
const [videoUrl, setVideoUrl] = useState(uri);
useS3UrlCheck(uri, documentRefId, caseId, caseType, unsignedUri, setVideoUrl);
return (
<WebView
source={{ html: vkycHtml(videoUrl) }}