TP-48456 | Agent Id Card Fixes | Ashish Deo (#705)

This commit is contained in:
Ashish Deo
2024-01-22 17:58:48 +05:30
committed by GitHub
parent 5d99250597
commit ecf5b8f4f3
4 changed files with 203 additions and 71 deletions

View File

@@ -1,74 +1,207 @@
import { StyleSheet, View } from 'react-native';
import React from 'react';
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, SCREEN_WIDTH } from '../../../RN-UI-LIB/src/styles';
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 { useAppSelector } from '../../hooks';
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';
import { getSyncTime } from '@hooks/capturingApi';
import { logError } from '@components/utlis/errorUtils';
import LineLoader from '@rn-ui-lib/components/suspense_loader/LineLoader';
import RetryIcon from '@assets/icons/RetryIcon';
import ScreenshotBlocker from '@components/utlis/ScreenshotBlocker';
import { getSelfieDocument } from '@actions/profileActions';
const PAGE_TITLE = 'Agent ID card';
const backHandler = () => {
goBack();
};
const getTodaysDate = async () => {
const timestamp = await getSyncTime();
const date = new Date(timestamp);
return date;
};
const AgentIdCard = () => {
const dispatch = useAppDispatch();
const [loading, setLoading] = useState(true);
const [retry, setRetry] = useState(false);
const setLoadingFalse = () => setLoading(false);
const setRetryTrue = () => setRetry(true);
const onRetry = () => {
dispatch(getSelfieDocument());
};
useEffect(() => {
ScreenshotBlocker.blockScreenshots();
return () => {
ScreenshotBlocker.unblockScreenshots();
}
}, []);
const [todaysDate, setTodaysDate] = useState(new Date());
const fetchTodaysDate = async () => {
try {
const date = await getTodaysDate();
setTodaysDate(date);
} catch (error) {
logError(error as Error);
}
};
useEffect(() => {
fetchTodaysDate();
}, [])
const {
originalImageUri,
optimizedImageUri,
agentName,
agentPhone,
validationDate,
agencyName,
agencyCode,
} = useAppSelector((state) => ({
originalImageUri: state.profile.originalImageUri,
agentName: state.user.user?.name!!,
agentPhone: state.user.user?.phoneNumber,
validationDate: state.profile.validationDate,
agencyName: state.profile.agencyName,
agencyCode: state.profile.agencyCode,
optimizedImageUri: state.profile.optimizedImageUri,
}));
const showRetry = useMemo(() => {
return !originalImageUri && !optimizedImageUri;
}, [optimizedImageUri, originalImageUri]);
const loaderConf = useMemo(()=>{
return [
{ width: 75, height: 25, style: { marginTop: 10, marginBottom: 20 } },
{ width: 0, height: 0, style: { marginTop: 280 } },
{ width: 150, height: 18, style: { marginTop: 15 } },
{ width: 200, height: 18, style: { marginTop: 20 } },
{ width: 100, height: 18, style: { marginTop: 20 } },
]
},[])
return (
<View style={[GenericStyles.p24, GenericStyles.alignCenter, { width: SCREEN_WIDTH - 32 }]}>
<NaviLogoWithTextIcon />
{agencyName && agencyCode !== NAVI_AGENCY_CODE ? (
<>
<Text small bold style={styles.greyColor}>
in association with
</Text>
<Text dark bold>
{agencyName}
</Text>
</>
) : null}
<View style={GenericStyles.mv16}>
<Avatar
loading={false}
size={160}
name={agentName}
dataURI={originalImageUri}
fallbackDataUri={optimizedImageUri}
/>
</View>
<Text small bold style={styles.greyColor}>
Valid as of {dateFormat(new Date(validationDate), BUSINESS_DATE_FORMAT)}
</Text>
<Heading type="h4" dark bold style={GenericStyles.mv4}>
{agentName}
</Heading>
<Text style={GenericStyles.mb4}>Collection agent</Text>
<Text light bold>
{agentPhone}
</Text>
</View>
<Layout>
<SafeAreaView>
<NavigationHeader onBack={backHandler} title={PAGE_TITLE} />
<View style={[GenericStyles.p24, GenericStyles.alignCenter, styles.container]}>
<View style={styles.avatarImage}>
<Avatar
loading={false}
size={280}
name={agentName}
dataURI={originalImageUri}
fallbackDataUri={optimizedImageUri}
onSuccess={setLoadingFalse}
onErrorFallback={setRetryTrue}
/>
</View>
{loading ? (
<>
{loaderConf.map((loaderProps, index) => (
<>
<LineLoader
key={index}
width={loaderProps.width}
height={loaderProps.height}
style={[loaderProps.style, styles.lineLoader]}
/>
</>
))}
{(retry || showRetry && (
<View style={styles.retryContainer}>
<Pressable
style={[GenericStyles.row, GenericStyles.alignCenter]}
onPress={onRetry}
>
<RetryIcon />
<Text style={[GenericStyles.ml4, styles.retryText]}>Retry loading ID card</Text>
</Pressable>
</View>
)) || null}
</>
) : (
<>
<NaviLogoWithTextIcon />
{agencyName && agencyCode !== NAVI_AGENCY_CODE ? (
<>
<Text small bold style={styles.greyColor}>
in association with
</Text>
<Text dark bold>
{agencyName}
</Text>
</>
) : null}
<View style={styles.avatarMargin}>
<Text style={styles.greyColor}>
Valid on {dateFormat(new Date(todaysDate), BUSINESS_DATE_FORMAT)}
</Text>
<Heading type="h4" dark bold style={GenericStyles.mv4}>
{agentName}
</Heading>
<Text style={styles.greyColor}>
{agentPhone}
</Text>
</View>
</>
)}
</View>
</SafeAreaView>
</Layout>
);
};
export default AgentIdCard;
const styles = StyleSheet.create({
container: {
...GenericStyles.relative,
},
greyColor: {
color: COLORS.TEXT.GREY,
},
lineLoader: {
borderRadius: 20,
},
avatarImage: {
...GenericStyles.absolute,
marginTop: 70,
},
avatarMargin: {
alignItems: 'center',
marginTop: 310,
},
retryContainer: {
marginTop: 30,
},
retryText: {
color: COLORS.TEXT.BLUE,
},
});

View File

@@ -1,11 +1,10 @@
import React, { useEffect, useMemo, useState } from 'react';
import React, { useMemo, useState } from 'react';
import {
Alert,
Linking,
Pressable,
ScrollView,
StyleSheet,
TouchableHighlight,
TouchableOpacity,
View,
} from 'react-native';
@@ -33,18 +32,16 @@ import CaseItem from '../allCases/CaseItem';
import { IUserRole, MY_CASE_ITEM } from '../../reducer/userSlice';
import QuestionMarkIcon from '../../assets/icons/QuestionMarkIcon';
import IDCardImageCapture from './IDCardImageCapture';
import AgentIdCard from './AgentIdCard';
import TranslucentModal from '../../../RN-UI-LIB/src/components/TranslucentModal/TranslucentModal';
import ArrowSolidIcon from '../../../RN-UI-LIB/src/Icons/ArrowSolidIcon';
import { getSelfieDocument } from '../../action/profileActions';
import { ImageApprovalStatus } from '../../reducer/profileSlice';
import FloatingBannerCta from '@common/FloatingBannerCta';
import AttendanceIcon from '@assets/icons/AttendanceIcon';
import GoogleFormModal from '@screens/allCases/GoogleFormModal';
import { PageRouteEnum } from '@screens/auth/ProtectedRouter';
const Profile: React.FC = () => {
const [buttonPressedCount, setButtonPressedCount] = useState(0);
const [showIdCard, setShowIdCard] = useState(false);
const dispatch = useAppDispatch();
const {
originalImageUri,
@@ -129,16 +126,12 @@ const Profile: React.FC = () => {
const helpButtonClickHandler = () => Linking.openURL(supportLink);
const toggleIdCard = () => setShowIdCard((prev) => !prev);
const hideUploadImageBtn =
approvalStatus === ImageApprovalStatus.PENDING ||
approvalStatus === ImageApprovalStatus.APPROVED;
const handleViewIdCard = () => {
toggleIdCard();
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_ID_CARD_CLICKED);
};
const showCompletedCases = !isTeamLead || selectedAgent?.referenceId === MY_CASE_ITEM.referenceId;
@@ -157,20 +150,22 @@ const Profile: React.FC = () => {
showAvatarIcon
bottomActionable={
originalImageUri && pendingCases?.length ? (
<TouchableHighlight
onPress={handleViewIdCard}
underlayColor={COLORS.HIGHLIGHTER.LIGHT_BUTTON}
style={styles.bottomActionable}
<Pressable
onPress={() => {
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_ID_CARD_CLICKED);
navigateToScreen(PageRouteEnum.AGENT_ID_CARD);
}}
style={styles.bottomActionable}
>
<View style={[GenericStyles.row, GenericStyles.alignStart]}>
<Text small style={styles.whiteText}>
View ID card
</Text>
<View style={{ transform: [{ rotate: '180deg' }] }}>
<ArrowSolidIcon fillColor={COLORS.TEXT.WHITE} />
<View style={[GenericStyles.row, GenericStyles.alignStart]}>
<Text small style={styles.whiteText}>
View ID card
</Text>
<View style={{ transform: [{ rotate: '180deg' }] }}>
<ArrowSolidIcon fillColor={COLORS.TEXT.WHITE} />
</View>
</View>
</View>
</TouchableHighlight>
</Pressable>
) : null
}
rightActionable={
@@ -280,15 +275,7 @@ const Profile: React.FC = () => {
)}
<GoogleFormModal showForm={showForm} setShowForm={setShowForm} />
{pendingCases?.length ? (
<TranslucentModal
visible={showIdCard}
onRequestClose={() => setShowIdCard(false)}
flipAnimation
>
<AgentIdCard />
</TranslucentModal>
) : null}
</View>
);
};

View File

@@ -44,6 +44,7 @@ import NearbyCases from '@screens/allCases/NearbyCases';
import usePolling from "@hooks/usePolling";
import {getFirestoreResyncIntervalInMinutes} from "@common/AgentActivityConfigurableConstants";
import useResyncFirebase from "@hooks/useResyncFirebase";
import AgentIdCard from '@screens/Profile/AgentIdCard';
const Stack = createNativeStackNavigator();
@@ -60,6 +61,7 @@ export enum PageRouteEnum {
FILTERED_CASES = 'filteredCases',
NEARBY_CASES = 'nearbyCases',
GEOLOCATION_OLD_FEEDBACKS = 'geolocationOldFeedbacks',
AGENT_ID_CARD = 'AgentIdCard'
}
const ProtectedRouter = () => {
@@ -335,6 +337,16 @@ const ProtectedRouter = () => {
}}
listeners={getScreenFocusListenerObj}
/>
<Stack.Screen
name={PageRouteEnum.AGENT_ID_CARD}
component={AgentIdCard}
options={{
header: () => null,
animation: 'none',
animationDuration: SCREEN_ANIMATION_DURATION,
}}
listeners={getScreenFocusListenerObj}
/>
<Stack.Screen
name="AddNewNumber"
component={AddNewNumber}

View File

@@ -151,7 +151,7 @@ export enum DOCUMENT_TYPE {
export enum LegalDocumentFullName {
LDN = 'Loan_Demand_Notice',
LRN = 'Loan_Recovery_Notice',
LRN = 'Loan_Recall_Notice',
}
export enum DocumentTitle {