From 6791014fff4ebab40b4f8dcad5507c299046bab2 Mon Sep 17 00:00:00 2001 From: Aman Sethi Date: Tue, 21 Mar 2023 13:00:00 +0530 Subject: [PATCH] Tp 21873 sethi (#165) * intermediate screen text fix TP-21873 * image bug fix TP-21873 * intermediate screen text issue fix TP-21873 * otp screen fix TP-21873 * remove commented code TP-21873 * success image changes TP-21873 * submodule update TP-21873 * fix images issue TP-21873 --- RN-UI-LIB | 2 +- src/components/utlis/commonFunctions.ts | 12 ++++- src/hooks/useCustomerImage.ts | 24 +++++++--- src/reducer/loginSlice.ts | 4 ++ src/screens/allCases/CaseItemAvatar.tsx | 31 ++++++++++-- src/screens/allCases/ListItem.tsx | 4 +- .../caseDetails/UserDetailsSection.tsx | 29 ++++++++++-- src/screens/login/OtpInput.tsx | 8 +++- src/screens/login/OtpText.tsx | 47 ++++++++++--------- src/screens/todoList/TodoList.tsx | 28 ++++++++--- 10 files changed, 137 insertions(+), 52 deletions(-) diff --git a/RN-UI-LIB b/RN-UI-LIB index 9b83ba94..82e33fdb 160000 --- a/RN-UI-LIB +++ b/RN-UI-LIB @@ -1 +1 @@ -Subproject commit 9b83ba94da83ae3ab77bb888e5f375420352d3a2 +Subproject commit 82e33fdb8ff94ba27f8c8f43c091cb62b67b77ef diff --git a/src/components/utlis/commonFunctions.ts b/src/components/utlis/commonFunctions.ts index 7f3696ef..aad2c2d7 100644 --- a/src/components/utlis/commonFunctions.ts +++ b/src/components/utlis/commonFunctions.ts @@ -1,12 +1,13 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; import RNFetchBlob from "rn-fetch-blob"; -import { getPrefixBase64Image, MimeType } from "../../common/Constants"; +import { getPrefixBase64Image, LocalStorageKeys, MimeType } from "../../common/Constants"; import { Address, PhoneNumber } from "../../screens/caseDetails/interface"; import NetInfo from "@react-native-community/netinfo"; import Clipboard from '@react-native-clipboard/clipboard'; import { stringify } from './stringifyUtils'; import address from "../form/components/Address"; import { useWindowDimensions } from 'react-native'; +import { GlobalImageMap } from '../../../App'; import { GenericType } from '../../common/GenericTypes'; @@ -124,7 +125,14 @@ export const getDynamicBottomSheetHeightPercentageFn = (headerOffset = 100, rowH }) } +export const saveToGlobalImageMap = async (caseId: string, image: string) => { + GlobalImageMap[caseId] = image; + await setAsyncStorageItem( + LocalStorageKeys.GLOBAL_IMAGE_MAP, + GlobalImageMap, + ); +}; export const allSettled = (promises: Promise[]) => Promise.all( promises.map(p => p.then(value => ({ status: 'fulfilled', value})).catch(value => ({ status: 'rejected', value}))), - ); \ No newline at end of file + ); diff --git a/src/hooks/useCustomerImage.ts b/src/hooks/useCustomerImage.ts index 5135b282..9b250623 100644 --- a/src/hooks/useCustomerImage.ts +++ b/src/hooks/useCustomerImage.ts @@ -1,11 +1,14 @@ import React, { useEffect, useState } from 'react'; -import { setAsyncStorageItem } from './../components/utlis/commonFunctions'; +import { + setAsyncStorageItem, +} from './../components/utlis/commonFunctions'; import { CaseDetail } from '../screens/caseDetails/interface'; import { CaseAllocationType } from '../screens/allCases/interface'; -import { LocalStorageKeys } from '../common/Constants'; import { getSignedApi, ISignedRequest } from '../action/dataActions'; import { getBase64FromUrl } from '../components/utlis/commonFunctions'; import { GlobalImageMap } from '../../App'; +import { LocalStorageKeys } from '../common/Constants'; +import { useAppSelector } from '.'; const useCustomerImage = (caseDetails: CaseDetail) => { const [imageUrl, setImageUrl] = useState( @@ -13,6 +16,7 @@ const useCustomerImage = (caseDetails: CaseDetail) => { caseDetails?.customerInfo?.imageURL || caseDetails?.imageUrl, ); + const pinnedList = useAppSelector(state => state.allCases.pinnedList); const [error, setError] = useState(false); const [loading, setLoading] = useState(false); @@ -45,11 +49,17 @@ const useCustomerImage = (caseDetails: CaseDetail) => { const responseImage64 = await getBase64FromUrl(url); if (responseImage64) { setImageUrl(responseImage64); - GlobalImageMap[caseId] = responseImage64; - await setAsyncStorageItem( - LocalStorageKeys.GLOBAL_IMAGE_MAP, - GlobalImageMap, - ); + if ( + pinnedList.find( + item => item.caseReferenceId === caseId, + ) + ) { + GlobalImageMap[caseId] = responseImage64; + await setAsyncStorageItem( + LocalStorageKeys.GLOBAL_IMAGE_MAP, + GlobalImageMap, + ); + } } } else { setImageUrl(''); diff --git a/src/reducer/loginSlice.ts b/src/reducer/loginSlice.ts index 1eb2ce1c..a7dca281 100644 --- a/src/reducer/loginSlice.ts +++ b/src/reducer/loginSlice.ts @@ -34,6 +34,9 @@ const loginSlice = createSlice({ state.verifyOTPError = action.payload; state.isLoading = false; }, + resetVerifyOTPError: state => { + state.verifyOTPError = ''; + }, setFormLoading: (state, action) => { state.isLoading = action.payload; }, @@ -55,6 +58,7 @@ export const { setShowOTPScreen, setFormLoading, resetLoginForm, + resetVerifyOTPError, } = loginSlice.actions; export default loginSlice.reducer; diff --git a/src/screens/allCases/CaseItemAvatar.tsx b/src/screens/allCases/CaseItemAvatar.tsx index e6de0e43..0c5f98ce 100644 --- a/src/screens/allCases/CaseItemAvatar.tsx +++ b/src/screens/allCases/CaseItemAvatar.tsx @@ -1,9 +1,14 @@ import React from 'react'; import { StyleSheet, View } from 'react-native'; +import { GlobalImageMap } from '../../../App'; import Avatar from '../../../RN-UI-LIB/src/components/Avatar'; import UnsyncedIcon from '../../../RN-UI-LIB/src/Icons/UnsyncedIcon'; import { COLORS } from '../../../RN-UI-LIB/src/styles/colors'; -import { useAppDispatch, useAppSelector } from '../../hooks'; +import { + getBase64FromUrl, + saveToGlobalImageMap, +} from '../../components/utlis/commonFunctions'; +import { useAppSelector } from '../../hooks'; import useCustomerImage from '../../hooks/useCustomerImage'; import { CaseDetail } from '../caseDetails/interface'; import { ICaseItem } from './interface'; @@ -12,6 +17,7 @@ interface ICaseItemAvatar { caseData: ICaseItem; size?: number; showBorder?: boolean; + shouldHandleError?: boolean; } const RELATIVE_ASYNC_ICON_RIGHT_POSITION = -5; @@ -21,19 +27,33 @@ const CaseItemAvatar: React.FC = ({ caseData, size = 40, showBorder = false, + shouldHandleError, }) => { - const dispatch = useAppDispatch(); const refrenceId = caseData?.caseReferenceId || caseData?.id; const caseDetails: CaseDetail = useAppSelector( state => state.allCases.caseDetails?.[refrenceId]!!, ); - const [apiErrorCount, setApiErrorCount] = React.useState(0); const isSynced = caseDetails?.isSynced; - const { imageUrl, setError, loading } = useCustomerImage(caseDetails); + const { imageUrl, setImageUrl, setError, loading } = + useCustomerImage(caseDetails); const onError = async () => { - setError(true); + if (shouldHandleError) { + setError(true); + } else { + setImageUrl(''); + } + }; + + const onImageLoadSuccess = async () => { + if (!GlobalImageMap[caseDetails?.id]) { + const responseImage64 = await getBase64FromUrl(imageUrl); + if (responseImage64) { + const caseId = caseDetails?.id; + await saveToGlobalImageMap(caseId, responseImage64); + } + } }; const customerName = @@ -51,6 +71,7 @@ const CaseItemAvatar: React.FC = ({ onErrorFallback={onError} style={[showBorder && styles.border]} loading={loading} + onSuccess={onImageLoadSuccess} /> {!isSynced ? ( diff --git a/src/screens/allCases/ListItem.tsx b/src/screens/allCases/ListItem.tsx index 107803cb..698c12f7 100644 --- a/src/screens/allCases/ListItem.tsx +++ b/src/screens/allCases/ListItem.tsx @@ -46,7 +46,7 @@ const ListItem: React.FC = props => { return null; } - const { intermediateTodoListMap, selectedTodoListMap, caseDetails } = + const { intermediateTodoListMap, selectedTodoListMap, caseDetails, pinnedList } = useAppSelector(state => state.allCases); const detail = caseDetails[caseId]!!; @@ -128,7 +128,7 @@ const ListItem: React.FC = props => { : COLORS.BACKGROUND.PRIMARY, }, ]}> - + item?.caseReferenceId === caseId) ? true: false} caseData={caseData} /> {!isTodoItem && !isCompleted ? ( = props => { ); const ANIMATION_DURATION = 500; const [openImage, setOpenImage] = useState(false); - const { imageUrl, setError, loading } = useCustomerImage(caseDetail); + const { imageUrl, setError } = useCustomerImage(caseDetail); + const [errorModalImage, setErrorModalImage] = useState(false); + const handleOpenClose = useCallback(() => { setOpenImage(prev => !prev); @@ -86,6 +88,7 @@ const UserDetailsSection: React.FC = props => { showBorder size={64} caseData={caseDetail} + shouldHandleError /> @@ -155,7 +158,7 @@ const UserDetailsSection: React.FC = props => { '' )} - { GlobalImageMap[caseDetail?.id] ? @@ -174,13 +177,31 @@ const UserDetailsSection: React.FC = props => { GenericStyles.fill, GenericStyles.alignCenter, GenericStyles.row, + { + position: 'relative', + }, ]}> setError(true)} + onError={() => { + setError(true) + setErrorModalImage(true) + }} + onLoad={()=>{ + setErrorModalImage(false) + }} /> + { + errorModalImage ? + Image not available + : null + } : null} diff --git a/src/screens/login/OtpInput.tsx b/src/screens/login/OtpInput.tsx index 39e75a5b..af0ee03a 100644 --- a/src/screens/login/OtpInput.tsx +++ b/src/screens/login/OtpInput.tsx @@ -19,6 +19,7 @@ import { addClickstreamEvent } from '../../services/clickstreamEventService'; import { CLICKSTREAM_EVENT_NAMES } from '../../common/Constants'; import Layout from '../layout/Layout'; import otpText from "./OtpText"; +import { resetVerifyOTPError } from '../../reducer/loginSlice'; interface IOtpForm { otp: string; @@ -97,7 +98,12 @@ const OtpInput = () => { style={[styles.otpText]} keyboardType="phone-pad" onBlur={onBlur} - onChangeText={value => onChange(value)} + onChangeText={value => { + onChange(value) + if(verifyOTPError) { + dispatch(resetVerifyOTPError()); + } + }} value={value} maxLength={4} testID={'test_enter_otp'} diff --git a/src/screens/login/OtpText.tsx b/src/screens/login/OtpText.tsx index ca948042..42f78327 100644 --- a/src/screens/login/OtpText.tsx +++ b/src/screens/login/OtpText.tsx @@ -7,9 +7,11 @@ import Text from '../../../RN-UI-LIB/src/components/Text'; import {Countdown} from '../../components/countdown'; import {StyleSheet} from 'react-native'; import {COLORS} from '../../../RN-UI-LIB/src/styles/colors'; +import { GenericStyles } from '../../../RN-UI-LIB/src/styles'; const OtpText = () => { const [countDownComplete, setCountDownComplete] = useState(false); + const [countDownTimeLeft, setCountDownTimeLeft] = useState(30); const dispatch = useAppDispatch(); const {phoneNumber, verifyOTPError} = useSelector( @@ -24,35 +26,34 @@ const OtpText = () => { setCountDownComplete(true) }; - if (verifyOTPError) { - return ( - - {verifyOTPError}{' '} - - Resend OTP - - - ); - } - if (countDownComplete) { - return ( - - Enter 4 digits OTP or{' '} - - Resend OTP - - - ); - } return ( - + <> + {!countDownComplete && Resend OTP in{' '} setCountDownTimeLeft(timeLeft)} />{' '} - second(s) + second{ countDownTimeLeft > 1 && 's' } + } + + {verifyOTPError && ( + + {verifyOTPError}{' '} + + )} + { + countDownComplete && ( + + Resend OTP + + ) + } + + + ); }; diff --git a/src/screens/todoList/TodoList.tsx b/src/screens/todoList/TodoList.tsx index 2b6aaa83..c4bb1776 100644 --- a/src/screens/todoList/TodoList.tsx +++ b/src/screens/todoList/TodoList.tsx @@ -119,6 +119,12 @@ const TodoList = () => { const intermediateTodoListLength = intermediateTodoList.length; + const avCases = intermediateTodoList.filter((item) => { + if(caseDetails[item.caseReferenceId]?.caseType === CaseAllocationType.ADDRESS_VERIFICATION_CASE) { + return item; + } + }) + return ( @@ -128,22 +134,27 @@ const TodoList = () => { } selected`} onBack={handleBack} /> - + { avCases?.length > 0 && - - Sharing a message of your visit + + Sharing a message to only onboarding - - The selected customer{intermediateTodoListLength > 1 ? 's' : ''} will recieve a message - about your visit. Are you sure you want to proceed? + + customers + + + The selected onboarding customer{avCases?.length > 1 ? 's' : ''} will + + + receive a message about your visit - + } } @@ -213,6 +224,9 @@ const styles = StyleSheet.create({ opacity: 0.6, bottom: 77, height: '100%', + }, + descriptionText: { + color: '#6770C4' } });