Animation case detail || Aman Singh (#61)

* case details, animation and data validations

* changed linting issue

* changed submodule path
This commit is contained in:
Aman Singh
2023-01-16 15:23:57 +05:30
committed by GitHub Enterprise
parent cb660f888b
commit 6463c24ffa
12 changed files with 400 additions and 171 deletions

View File

@@ -1,25 +1,25 @@
import crashlytics from '@react-native-firebase/crashlytics';
import { RouteProp } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import React from 'react';
import { getUniqueId } from 'react-native-device-info';
import { useSelector } from 'react-redux';
import { _map } from './RN-UI-LIB/src/utlis/common';
import { GenericType } from './src/common/GenericTypes';
import Widget from './src/components/form';
import { setGlobalUserData } from './src/constants/Global';
import RealTemplate from './src/data/RealTemplateData.json';
import { useAppDispatch } from './src/hooks';
import useFirestoreUpdates from './src/hooks/useFirestoreUpdates';
import { setDeviceId } from './src/reducer/userSlice';
import AllCasesMain from './src/screens/allCases';
import CaseDetails from './src/screens/caseDetails/CaseDetails';
import interactionsHandler from './src/screens/caseDetails/interactionsHandler';
import Login from './src/screens/login';
import OtpInput from './src/screens/login/OtpInput';
import Profile from './src/screens/Profile';
import TodoList from './src/screens/todoList/TodoList';
import { RootState } from './src/store/store';
import Profile from './src/screens/Profile';
import interactionsHandler from './src/screens/caseDetails/interactionsHandler';
import useFirestoreUpdates from './src/hooks/useFirestoreUpdates';
import crashlytics from '@react-native-firebase/crashlytics';
import { RouteProp } from '@react-navigation/native';
import { GenericType } from './src/common/GenericTypes';
const ANIMATION_DURATION = 300;
@@ -80,7 +80,7 @@ const ProtectedRouter = () => {
options={{
header: () => null,
animationDuration: ANIMATION_DURATION,
animation: 'slide_from_right',
animation: 'none',
}}
listeners={getScreenFocusListenerObj}
/>

View File

@@ -37,6 +37,7 @@ export const getAllCases =
export const getAllCaseDetails =
(data: Array<ICaseItem>) => (dispatch: AppDispatch) => {
if(!data) return;
const caseList = data.map(caseItem => caseItem?.caseReferenceId);
const url = getApiUrl(ApiKeys.CASE_DETAIL);
axiosInstance

View File

@@ -127,7 +127,7 @@ axiosInstance.interceptors.response.use(
) {
const errorString = getErrorMessage(error);
if (!config.headers.donotHandleError) {
toast({ type: 'error', text1: JSON.stringify(errorString) });
toast({ type: 'error', text1:errorString || "Something went wrong" });
}
if (response.status === 401) {

View File

@@ -1,13 +1,13 @@
import { createSlice } from '@reduxjs/toolkit';
import { getCurrentScreen, navigateToScreen } from '../components/utlis/navigationUtlis';
import { CurrentTask, ICaseItem, IFilter } from '../screens/allCases/interface';
import {
FirestoreUpdateTypes,
} from '../common/Constants';
import { CaseDetail } from '../screens/caseDetails/interface';
import { CaseUpdates } from '../hooks/useFirestoreUpdates';
import { updateRecordsOnCustomerDbFromCaseList } from '../components/utlis/customerDbHelper';
import { _map } from '../../RN-UI-LIB/src/utlis/common';
import {
FirestoreUpdateTypes
} from '../common/Constants';
import { updateRecordsOnCustomerDbFromCaseList } from '../components/utlis/customerDbHelper';
import { getCurrentScreen, navigateToScreen } from '../components/utlis/navigationUtlis';
import { CaseUpdates } from '../hooks/useFirestoreUpdates';
import { CurrentTask, ICaseItem, IFilter } from '../screens/allCases/interface';
import { CaseDetail } from '../screens/caseDetails/interface';
export type ICasesMap = { [key: string]: ICaseItem };
@@ -80,6 +80,7 @@ const allCasesSlice = createSlice({
},
setCasesListData: (state, action) => {
const { allCases } = action.payload;
if(!allCases) return;
// TODO add type
const listData: Array<any> = [];
if (allCases?.length) {

View File

@@ -24,6 +24,7 @@ interface ICaseReducer {
toBeSynced: any;
allCases: Array<Data>;
templateData: any;
showAlternateText: string;
}
const initialState = {
@@ -32,6 +33,7 @@ const initialState = {
toBeSynced: {},
allCases: [],
templateData: {},
showAlternateText: ""
} as ICaseReducer;
export const caseSlice = createSlice({
@@ -77,22 +79,18 @@ export const caseSlice = createSlice({
updateTemplateData: (state, action) => {
state.templateData = action.payload;
},
setAllCases: (state, action) => {
state.allCases = action.payload;
},
updateDate: (state, action) => {
const { date } = action.payload;
state.loanInfo.allocationDate = date;
updateAlternateHeader: (state, action) => {
state.showAlternateText = action.payload;
},
},
});
export const {
updateInteraction,
setAllCases,
deleteInteraction,
updateTemplateData,
deleteJourney,
updateAlternateHeader
} = caseSlice.actions;
export default caseSlice.reducer;

View File

@@ -1,18 +1,20 @@
import React from 'react';
import {ICaseItem} from './interface';
import RoundCheckIcon from '../../icons/RoundCheckIcon';
import {useAppDispatch, useAppSelector} from '../../hooks';
import {CaseDetail} from '../caseDetails/interface';
import { StyleSheet, View } from 'react-native';
import Avatar from '../../../RN-UI-LIB/src/components/Avatar';
import UnsyncedIcon from '../../../RN-UI-LIB/src/Icons/UnsyncedIcon';
import {StyleSheet, View} from 'react-native';
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
import { getSignedURLs } from '../../action/dataActions';
import { getImage64FromCaseId } from '../../components/utlis/customerDbHelper';
import { useAppDispatch, useAppSelector } from '../../hooks';
import RoundCheckIcon from '../../icons/RoundCheckIcon';
import { CaseDetail } from '../caseDetails/interface';
import { ICaseItem } from './interface';
interface ICaseItemAvatar {
caseSelected?: boolean;
caseData: ICaseItem;
size?: number;
showBorder?: boolean;
}
const MAX_API_CALL = 3;
@@ -20,11 +22,12 @@ const MAX_API_CALL = 3;
const CaseItemAvatar: React.FC<ICaseItemAvatar> = ({
caseSelected = false,
caseData,
size = 32
size = 32,
showBorder = false,
}) => {
const dispatch = useAppDispatch();
const {caseReferenceId} = caseData;
const { caseReferenceId } = caseData;
const caseDetails: CaseDetail = useAppSelector(
state => state.allCases.caseDetails?.[caseReferenceId],
);
@@ -34,50 +37,54 @@ const CaseItemAvatar: React.FC<ICaseItemAvatar> = ({
const isSynced = caseDetails?.isSynced;
React.useEffect(() => {
if (caseDetails?.customerInfo?.imageURL) {
(async () => {
let image64 = await getImage64FromCaseId(caseDetails?.id);
if (image64) { // if image exist in WM db, then setting the base64
if (image64) {
// if image exist in WM db, then setting the base64
setImageUrl(image64);
} else {
setImageUrl(caseDetails.customerInfo.imageURL)
setImageUrl(caseDetails.customerInfo.imageURL);
}
})();
})();
}
}, [caseDetails?.customerInfo?.imageURL]);
const onError = async () => {
if (apiErrorCount < MAX_API_CALL) {
dispatch(getSignedURLs([imageUrl])).then((resp) => {
dispatch(getSignedURLs([imageUrl])).then(resp => {
if (resp?.[imageUrl]) {
setApiErrorCount(apiErrorCount => apiErrorCount+1);
setImageUrl(resp[imageUrl])
setApiErrorCount(apiErrorCount => apiErrorCount + 1);
setImageUrl(resp[imageUrl]);
}
})
});
}
}
};
return (
<View>
{
!caseSelected ? (
<View>
<Avatar
size={size}
name={caseDetails?.customerInfo?.name || caseDetails?.customerInfo?.customerName }
dataURI={imageUrl}
onErrorFallback={onError}
/>
{!isSynced ? (
<View style={styles.unsyncedIcon}>
<UnsyncedIcon />
</View>
) : null}
</View>
) : <RoundCheckIcon />
}
{!caseSelected ? (
<View>
<Avatar
size={size}
name={
caseDetails?.customerInfo?.name ||
caseDetails?.customerInfo?.customerName
}
dataURI={imageUrl}
onErrorFallback={onError}
style={[showBorder && styles.border]}
/>
{!isSynced ? (
<View style={styles.unsyncedIcon}>
<UnsyncedIcon />
</View>
) : null}
</View>
) : (
<RoundCheckIcon />
)}
</View>
);
};
@@ -88,6 +95,10 @@ const styles = StyleSheet.create({
left: 14,
top: 14,
},
border: {
borderColor: COLORS.BORDER.BLUE,
borderWidth: 2
},
});
export default CaseItemAvatar;

View File

@@ -0,0 +1,64 @@
import React, { useEffect, useRef } from 'react';
import { Animated, StyleSheet } from 'react-native';
import Avatar from '../../../RN-UI-LIB/src/components/Avatar';
import Heading from '../../../RN-UI-LIB/src/components/Heading';
import NavigationHeader from '../../../RN-UI-LIB/src/components/NavigationHeader';
import { GenericStyles } from '../../../RN-UI-LIB/src/styles';
import { goBack } from '../../components/utlis/navigationUtlis';
import { useAppSelector } from '../../hooks';
import { CaseDetail } from './interface';
const AlternateHeader: React.FC<{ imageUrl: string; name: string }> = props => {
const { name, imageUrl } = props;
const slideInUpAnimation = useRef(new Animated.Value(10)).current;
useEffect(() => {
Animated.timing(slideInUpAnimation, {
toValue: 0,
duration: 300,
useNativeDriver: true
}).start()
}, [])
return (
<Animated.View style={[GenericStyles.row, {transform: [{translateY : slideInUpAnimation}]}]}>
<Avatar name={name} dataURI={imageUrl} />
<Heading
type={'h4'}
bold
style={[
GenericStyles.whiteText,
GenericStyles.ml8,
{ alignItems: 'center', marginTop: 2 },
]}>
{name}
</Heading>
</Animated.View>
);
};
const CaseDetailHeader: React.FC<{ caseDetail: CaseDetail }> = props => {
const { caseDetail } = props;
const showHeader = useAppSelector(state => state.case.showAlternateText);
return (
<NavigationHeader
title={
showHeader.length ? (
<AlternateHeader
name={caseDetail?.customerInfo?.customerName}
imageUrl={caseDetail?.customerInfo?.imageURL}
/>
) : (
''
)
}
onBack={goBack}
/>
);
};
export default CaseDetailHeader;
const styles = StyleSheet.create({});

View File

@@ -1,22 +1,27 @@
import React from 'react';
import React, { useEffect, useRef } from 'react';
import {
Animated,
RefreshControl,
SafeAreaView,
ScrollView,
StatusBar,
StyleSheet,
View,
View
} from 'react-native';
import Heading from '../../../RN-UI-LIB/src/components/Heading';
import NavigationHeader from '../../../RN-UI-LIB/src/components/NavigationHeader';
import LineLoader from '../../../RN-UI-LIB/src/components/suspense_loader/LineLoader';
import Button from '../../../RN-UI-LIB/src/components/Button';
import SuspenseLoader from '../../../RN-UI-LIB/src/components/suspense_loader/SuspenseLoader';
import {GenericStyles, SCREEN_WIDTH} from '../../../RN-UI-LIB/src/styles';
import {COLORS} from '../../../RN-UI-LIB/src/styles/colors';
import {
GenericStyles,
getShadowStyle, SCREEN_WIDTH
} from '../../../RN-UI-LIB/src/styles';
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
import { getSingleCaseDetail } from '../../action/dataActions';
import { navigateToScreen } from '../../components/utlis/navigationUtlis';
import {useAppDispatch, useAppSelector} from '../../hooks';
import { useAppDispatch, useAppSelector } from '../../hooks';
import useRefresh from '../../hooks/useRefresh';
import CaseDetailsHeader from './CaseDetailsHeader';
import { updateAlternateHeader } from '../../reducer/caseReducre';
import { CaseStatuses } from '../allCases/interface';
import CaseDetailsHeader from './CaseDetailHeader';
import CallingBottomSheet from './journeyStepper/CallingBottomSheet';
import TaskStepper from './journeyStepper/TaskStepper';
import TaskLoader from './TaskLoader';
import UserDetailsSection from './UserDetailsSection';
@@ -31,39 +36,118 @@ interface ICaseDetails {
const CaseDetails: React.FC<ICaseDetails> = props => {
const {
route: {
params: {caseId},
params: { caseId },
},
} = props;
const dispatch = useAppDispatch();
const detailObject = useAppSelector(
const caseDetail = useAppSelector(
state => state.allCases.caseDetails[caseId],
);
const [showCallingBottomSheet, setShowCallingBottomSheet] =
React.useState(false);
const offset = useRef(new Animated.Value(0)).current;
const [showHeader, setShowHeader] = React.useState(false);
const { refreshing, onRefresh } = useRefresh(() =>
dispatch(getSingleCaseDetail([caseId])),
);
const handleCustomerCall = () => {
// if(mobileNumbers?.length > 0) {
// setShowPhoneNumberBottomSheet(true)
// return;
// }
// setSelectedPhoneNumber(mobileNumbers[0]);
setShowCallingBottomSheet(true);
};
const opacityAnimation = useRef(new Animated.Value(0)).current;
const isCaseClosedOrCompleted =
caseDetail.caseStatus === CaseStatuses.CLOSED ||
caseDetail.caseStatus === CaseStatuses.FORCE_CLOSE ||
caseDetail.caseStatus === CaseStatuses.EXPIRED;
const duration = 600;
const slideInUpJourney = new Animated.Value(1000);
useEffect(() => {
Animated.timing(slideInUpJourney, {
toValue: -58,
duration: duration,
useNativeDriver: true,
}).start();
Animated.timing(opacityAnimation, {
toValue: 1,
duration: duration,
useNativeDriver: true,
}).start();
}, []);
const {refreshing, onRefresh} = useRefresh(() => dispatch(getSingleCaseDetail([caseId])));
return (
<SafeAreaView
style={[GenericStyles.fill, GenericStyles.whiteBackground]}>
<StatusBar backgroundColor={COLORS.BACKGROUND.HEADER} />
<ScrollView
stickyHeaderIndices={[0]}
onScroll={event => {
const scrolling = event.nativeEvent.contentOffset.y;
if (scrolling > 19) {
dispatch(updateAlternateHeader(caseDetail?.customerInfo?.customerName));
} else {
dispatch(updateAlternateHeader(""));
}
}}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={onRefresh}
/>
}>
<NavigationHeader title={'Case Detail'} onBack={()=> navigateToScreen("Home")} />
{/* <CaseDetailsHeader /> */}
<View style={GenericStyles.p16}>
<UserDetailsSection caseDetail={detailObject} />
<CaseDetailsHeader caseDetail={caseDetail} />
<UserDetailsSection caseDetail={caseDetail} />
<Animated.View
style={[
GenericStyles.whiteBackground,
{
width: SCREEN_WIDTH * 0.93,
alignSelf: 'center',
borderRadius: 16,
},
getShadowStyle(2),
{ opacity: opacityAnimation },
{ transform: [{ translateY: slideInUpJourney }] },
]}>
<SuspenseLoader
loading={!detailObject.tasks}
loading={!caseDetail.tasks}
fallBack={<TaskLoader />}>
<TaskStepper caseDetail={detailObject} />
<TaskStepper caseDetail={caseDetail} />
</SuspenseLoader>
</View>
</Animated.View>
{!isCaseClosedOrCompleted && (
<View
style={[
GenericStyles.row,
styles.journeyContainer,
]}>
<Button
style={[styles.callCustomerButton]}
title="Call customer"
variant="secondary"
onPress={handleCustomerCall}
/>
</View>
)}
</ScrollView>
<CallingBottomSheet
setShowCallingBottomSheet={setShowCallingBottomSheet}
showCallingBottomSheet={showCallingBottomSheet}
selectedPhoneNumber={caseDetail.customerInfo.primaryPhoneNumber}
/>
</SafeAreaView>
);
};
@@ -72,6 +156,15 @@ export const styles = StyleSheet.create({
navigationContainer: {
height: 48,
},
callCustomerButton: {
width: '100%',
marginVertical: 10,
},
journeyContainer: {
borderTopWidth: 1,
borderTopColor: COLORS.BORDER.PRIMARY,
borderStyle: 'dashed',
},
});
export default CaseDetails;

View File

@@ -1,32 +1,28 @@
import React, {useCallback, useState} from 'react';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import {
Animated,
Image,
Modal,
SafeAreaView,
StyleSheet,
TouchableOpacity,
View,
View
} from 'react-native';
import Avatar from '../../../RN-UI-LIB/src/components/Avatar';
import Heading from '../../../RN-UI-LIB/src/components/Heading';
import LineLoader from '../../../RN-UI-LIB/src/components/suspense_loader/LineLoader';
import SuspenseLoader from '../../../RN-UI-LIB/src/components/suspense_loader/SuspenseLoader';
import Text from '../../../RN-UI-LIB/src/components/Text';
import CloseIcon from '../../../RN-UI-LIB/src/Icons/CloseIcon';
import UnsyncedIcon from '../../../RN-UI-LIB/src/Icons/UnsyncedIcon';
import {GenericStyles} from '../../../RN-UI-LIB/src/styles';
import {COLORS} from '../../../RN-UI-LIB/src/styles/colors';
import {dateFormat} from '../../../RN-UI-LIB/src/utlis/dates';
import CalenderIcon from '../../assets/icons/CalenderIcon';
import DocumentIcon from '../../assets/icons/DocumentIcon';
import IconLabel from '../../common/IconLabel';
import {
GenericStyles
} from '../../../RN-UI-LIB/src/styles';
import { COLORS } from '../../../RN-UI-LIB/src/styles/colors';
import { dateFormat } from '../../../RN-UI-LIB/src/utlis/dates';
import { decideLoadingState } from '../../components/utlis/commonFunctions';
import CaseItemAvatar from '../allCases/CaseItemAvatar';
import { ICaseItem } from '../allCases/interface';
import {
CaseDetail,
LoanAccountStatusUIMapping,
LoanTypeUIMapping,
CaseDetail, LoanTypeUIMapping
} from './interface';
interface IUserDetailsSection {
@@ -34,9 +30,10 @@ interface IUserDetailsSection {
}
const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
const {caseDetail = {} as CaseDetail} = props;
const {customerInfo, loanDetails} = caseDetail;
const { caseDetail = {} as CaseDetail } = props;
const { customerInfo, loanDetails } = caseDetail;
const textAnimationSlideInUp = useRef(new Animated.Value(0)).current;
const textAnimationFadeIn = useRef(new Animated.Value(0)).current;
const disbursalDate = dateFormat(
new Date(loanDetails?.disbursalDate),
'DD MMM, YYYY',
@@ -45,77 +42,140 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
new Date(caseDetail.allocatedAt),
'DD MMM, YYYY',
);
const ANIMATION_DURATION = 500;
const [openImage, setOpenImage] = useState<boolean>(false);
const handleOpenClose = useCallback(() => {
setOpenImage(prev => !prev);
}, []);
useEffect(() => {
Animated.timing(textAnimationSlideInUp, {
toValue: 0,
duration: ANIMATION_DURATION,
useNativeDriver: true,
}).start();
Animated.timing(textAnimationFadeIn, {
toValue: 1,
duration: ANIMATION_DURATION,
useNativeDriver: true,
}).start();
}, []);
const isSynced = caseDetail.isSynced;
return (
<View style={[GenericStyles.row, GenericStyles.pb16, styles.container, GenericStyles.mt12]}>
<SuspenseLoader
loading={!(customerInfo?.customerName || customerInfo?.name ) && !customerInfo?.imageURL}
fallBack={
<LineLoader
height={64}
width={64}
style={[GenericStyles.mb24, {borderRadius: 64 / 2}]}
/>
}>
<TouchableOpacity onPress={handleOpenClose}>
<CaseItemAvatar
size={64}
caseData={{...caseDetail, caseReferenceId: caseDetail?.id} as ICaseItem}
/>
</TouchableOpacity>
</SuspenseLoader>
<View style={[styles.infoContainer]}>
<View style={styles.contentContainer}>
<Animated.View
style={[
GenericStyles.row,
GenericStyles.p16,
{ paddingTop: 0 },
{ transform: [{ translateY: textAnimationSlideInUp }] },
{ opacity: textAnimationFadeIn },
]}>
<SuspenseLoader
loading={!(customerInfo?.customerName ||customerInfo?.name)}
fallBack={<LineLoader height={12} width={100} />}>
<Heading dark type="h3">
{customerInfo?.customerName || customerInfo?.name}
</Heading>
loading={
!(customerInfo?.customerName || customerInfo?.name) &&
!customerInfo?.imageURL
}
fallBack={
<LineLoader
height={64}
width={64}
style={[
GenericStyles.mb24,
{ borderRadius: 64 / 2 },
]}
/>
}>
<TouchableOpacity onPress={handleOpenClose}>
<CaseItemAvatar
showBorder
size={64}
caseData={
{
...caseDetail,
caseReferenceId: caseDetail?.id,
} as ICaseItem
}
/>
</TouchableOpacity>
</SuspenseLoader>
<View
style={[
GenericStyles.row,
GenericStyles.mb8,
GenericStyles.mt4,
]}>
<IconLabel
icon={<DocumentIcon />}
text={LoanTypeUIMapping[loanDetails?.loanType]}
/>
<IconLabel
containerStyle={GenericStyles.ml10}
text={
LoanAccountStatusUIMapping[
loanDetails?.loanAccountStatus
]
<View style={[styles.infoContainer]}>
<SuspenseLoader
loading={
!(customerInfo?.customerName || customerInfo?.name)
}
/>
fallBack={<LineLoader height={12} width={100} />}>
<Heading style={GenericStyles.whiteText} dark type="h3">
{customerInfo?.customerName || customerInfo?.name}
</Heading>
</SuspenseLoader>
<View
style={[
GenericStyles.row,
GenericStyles.mb8,
GenericStyles.mt4,
]}>
<Text
style={[
styles.chip,
GenericStyles.whiteBackground,
]}>
{LoanTypeUIMapping[loanDetails?.loanType]}
</Text>
<Text
style={[
styles.chip,
GenericStyles.whiteBackground,
GenericStyles.ml8,
]}>
{loanDetails?.tenureMonths}{' '}
{loanDetails?.tenureMonths > 1 ? 'Months' : 'Month'}
</Text>
</View>
<View style={GenericStyles.mb8}>
<Text style={GenericStyles.whiteText}>
Availed on{' '}
<Text style={GenericStyles.whiteText} dark bold>
{disbursalDate}
</Text>
</Text>
</View>
</View>
<View style={[GenericStyles.row, GenericStyles.mb8]}>
<IconLabel icon={<CalenderIcon />} text={disbursalDate} />
<IconLabel
text={`${loanDetails?.tenureMonths} ${
loanDetails?.tenureMonths > 1 ? 'Months' : 'Month'
}`}
containerStyle={GenericStyles.ml10}
/>
</View>
<View style={[GenericStyles.pt16]}>
<Text light style={[GenericStyles.fontSize15]}>
Allocated on <SuspenseLoader loading={decideLoadingState(allocationDate)} fallBack={<LineLoader height={12} width={70} />}>
<Text light>{allocationDate}</Text>
</Animated.View>
<Animated.View
style={[
GenericStyles.p16,
{ paddingTop: 0 },
{ transform: [{ translateY: textAnimationSlideInUp }] },
{ opacity: textAnimationFadeIn },
]}>
<View
style={{
borderTopWidth: 1,
borderTopColor: COLORS.BORDER.PRIMARY,
}}
/>
<View style={[GenericStyles.pt16, { alignItems: 'center' }]}>
<Text
light
style={[
[GenericStyles.fontSize15, GenericStyles.whiteText],
]}>
Case allocated on{' '}
<SuspenseLoader
loading={decideLoadingState(allocationDate)}
fallBack={<LineLoader height={12} width={70} />}>
<Text bold style={GenericStyles.whiteText} light>
{allocationDate}
</Text>
</SuspenseLoader>
</Text>
</View>
</View>
</Animated.View>
<Modal
animationType={'slide'}
visible={openImage}
@@ -123,7 +183,7 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
<SafeAreaView
style={[
GenericStyles.fill,
{backgroundColor: COLORS.BACKGROUND.HEADER},
{ backgroundColor: COLORS.BACKGROUND.HEADER },
]}>
<View style={GenericStyles.p16}>
<TouchableOpacity onPress={handleOpenClose}>
@@ -138,8 +198,8 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
]}>
<Image
style={[GenericStyles.fill, styles.imageStyle]}
source={{uri: customerInfo?.imageURL}}
resizeMode={'contain'}
source={{ uri: customerInfo?.imageURL }}
resizeMode={'stretch'}
/>
</View>
</SafeAreaView>
@@ -149,15 +209,11 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
};
const styles = StyleSheet.create({
container: {
borderBottomWidth: 1,
borderBottomColor: COLORS.BORDER.PRIMARY,
},
infoContainer: {
marginLeft: 16,
},
imageStyle: {
height: 300,
height: 500,
},
backgroundColor: {
backgroundColor: COLORS.BACKGROUND.HEADER,
@@ -167,6 +223,15 @@ const styles = StyleSheet.create({
left: 45,
top: 45,
},
chip: {
paddingHorizontal: 8,
paddingVertical: 2,
borderRadius: 6,
},
contentContainer: {
backgroundColor: COLORS.BACKGROUND.HEADER,
paddingBottom: 60,
},
});
export default UserDetailsSection;

View File

@@ -12,6 +12,7 @@ const interactionsHandler = () => {
const allCasesDetails = useAppSelector(state => state.allCases.caseDetails);
useEffect(() => {
console.log("getting called")
if(!allCasesDetails) return;
let notSyncedCases: Array<any> = [];
_map(allCasesDetails, (el)=> {
console.log(allCasesDetails[el]?.isSynced === false && allCasesDetails[el].isApiCalled === false)

View File

@@ -1,19 +1,12 @@
import React from 'react';
import { PixelRatio, StyleSheet, View } from 'react-native';
import Button from '../../../../RN-UI-LIB/src/components/Button';
import Heading from '../../../../RN-UI-LIB/src/components/Heading';
import { GenericStyles } from '../../../../RN-UI-LIB/src/styles';
import { COLORS } from '../../../../RN-UI-LIB/src/styles/colors';
import { navigateToScreen } from '../../../components/utlis/navigationUtlis';
import {
CaseStatuses,
CurrentTask,
TaskTitleUIMapping,
CaseStatuses
} from '../../allCases/interface';
import { CaseDetail, Context, CONTEXT_TASK_STATUSES, Task } from '../interface';
import CallingBottomSheet from './CallingBottomSheet';
import StepperHeader, { STEPPER_STATE } from './StepperHeader';
import TaskContent from './TaskContent';
import { CaseDetail } from '../interface';
import ClosedStepperRenderer from "./ClosedStepperRenderer";
import OpenStepperRenderer from "./OpenStepperRenderer";
@@ -47,16 +40,18 @@ const TaskStepper: React.FC<ITaskStepper> = props => {
return (
<>
<View style={[GenericStyles.p16]}>
<Heading type="h3" style={styles.header} dark bold>
<View style={[{paddingBottom: 0}]}>
<Heading type="h3" style={[styles.header, GenericStyles.p16]} dark bold>
Addresses
</Heading>
<View style={[GenericStyles.p16, {paddingTop:0, paddingBottom: 0}]}>
{
isCaseClosedOrCompleted ? <ClosedStepperRenderer tasks={caseDetail.tasks} context={caseDetail.context} currentTask={caseDetail.currentTask} />
: <OpenStepperRenderer tasks={caseDetail.tasks} context={caseDetail.context} currentTask={caseDetail.currentTask} caseReferenceId={caseDetail.id} />
}
</View>
</View>
{ !isCaseClosedOrCompleted && (
{/* { !isCaseClosedOrCompleted && (
<View style={[GenericStyles.row, styles.journeyContainer]}>
<Button
style={[styles.callCustomerButton]}
@@ -65,7 +60,7 @@ const TaskStepper: React.FC<ITaskStepper> = props => {
onPress={handleCustomerCall}
/>
</View>
)}
)} */}
{/* commenting this since we don't have mobile numbers as of right now
<PhoneNumberSelectionBottomSheet
showPhoneNumberBottomSheet={showPhoneNumberBottomSheet}
@@ -75,11 +70,11 @@ const TaskStepper: React.FC<ITaskStepper> = props => {
setShowCallingBottomSheet={setShowCallingBottomSheet}
setSelectedPhoneNumber={setSelectedPhoneNumber}
/>*/}
<CallingBottomSheet
{/* <CallingBottomSheet
setShowCallingBottomSheet={setShowCallingBottomSheet}
showCallingBottomSheet={showCallingBottomSheet}
selectedPhoneNumber={caseDetail.customerInfo.primaryPhoneNumber}
/>
/> */}
</>
);
};