Merge pull request #16 from medici/case-details-fixes

Case details and call sheet fixes
This commit is contained in:
Aman Chaturvedi
2022-12-29 15:27:28 +05:30
committed by GitHub Enterprise
6 changed files with 132 additions and 87 deletions

View File

@@ -1,18 +1,14 @@
import React from 'react';
import {
Alert,
RefreshControl,
SafeAreaView,
ScrollView,
StyleSheet,
View,
} from 'react-native';
import Button from '../../../RN-UI-LIB/src/components/Button';
import Text from '../../../RN-UI-LIB/src/components/Text';
import BackArrowIcon from '../../../RN-UI-LIB/src/Icons/BackArrowIcon';
import {GenericStyles} from '../../../RN-UI-LIB/src/styles';
import {goBack, navigateToScreen} from '../../components/utlis/navigationUtlis';
import {useAppDispatch, useAppSelector} from '../../hooks';
import {useAppSelector} from '../../hooks';
import CaseDetailsHeader from './CaseDetailsHeader';
import TaskStepper from './journeyStepper/TaskStepper';
import UserDetailsSection from './UserDetailsSection';
@@ -36,7 +32,7 @@ const CaseDetails: React.FC<ICaseDetails> = props => {
} = props;
const [refreshing, setRefreshing] = React.useState(false);
const dispatch = useAppDispatch();
const detailObject = useAppSelector(
state => state.allCases.caseDetails[caseId],
);
@@ -56,35 +52,10 @@ const CaseDetails: React.FC<ICaseDetails> = props => {
onRefresh={onRefresh}
/>
}>
<View
style={[
styles.navigationContainer,
GenericStyles.row,
GenericStyles.alignCenter,
GenericStyles.p16,
]}>
<BackArrowIcon onPress={goBack} />
</View>
<CaseDetailsHeader />
<View style={GenericStyles.p16}>
<UserDetailsSection caseDetail={detailObject} />
<TaskStepper caseDetail={detailObject} />
{/* <Button
style={{}}
title="Trigger journey"
variant="secondary"
onPress={() => Alert.alert("Confirm" , 'Are you sure you want to logout?', [
{
text: 'Cancle',
onPress: (value?: string) => console.log(value),
style: 'default'
},
{
text: 'Logout',
onPress: (value?: string) => console.log(value),
style: 'cancel'
},
])}
/> */}
</View>
</ScrollView>
</SafeAreaView>

View File

@@ -0,0 +1,42 @@
import {Pressable, StyleSheet, View} from 'react-native';
import React from 'react';
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 ArrowBackSmallIcon from '../../../RN-UI-LIB/src/Icons/ArrowBackSmallIcon';
const CaseDetailsHeader = () => {
const handleBackIconPress = () => {
navigateToScreen('Home');
};
return (
<View
style={[
GenericStyles.row,
GenericStyles.alignCenter,
styles.header,
]}>
<Pressable onPress={handleBackIconPress}>
<ArrowBackSmallIcon />
</Pressable>
<Heading type="h5" style={styles.headerLabel}>
Customer details
</Heading>
</View>
);
};
export default CaseDetailsHeader;
const styles = StyleSheet.create({
header: {
backgroundColor: COLORS.BACKGROUND.HEADER,
height: 56,
paddingLeft: 26,
},
headerLabel: {
color: COLORS.BACKGROUND.PRIMARY,
marginLeft: 16,
},
});

View File

@@ -1,22 +1,27 @@
import React, { useCallback, useState } from 'react';
import React, {useCallback, useState} from 'react';
import {
Image, Modal,
Image,
Modal,
Pressable,
SafeAreaView,
StyleSheet,
View
View,
} from 'react-native';
import Avatar from '../../../RN-UI-LIB/src/components/Avatar';
import Heading from '../../../RN-UI-LIB/src/components/Heading';
import Text from '../../../RN-UI-LIB/src/components/Text';
import CloseIcon from '../../../RN-UI-LIB/src/Icons/CloseIcon';
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 {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 { CaseDetail, LoanAccountStatusUIMapping, LoanTypeUIMapping } from './interface';
import {
CaseDetail,
LoanAccountStatusUIMapping,
LoanTypeUIMapping,
} from './interface';
interface IUserDetailsSection {
caseDetail: CaseDetail;
@@ -25,8 +30,14 @@ interface IUserDetailsSection {
const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
const {caseDetail} = props;
const {customerInfo, loanDetails} = caseDetail;
const disbursalDate = dateFormat(new Date(loanDetails.disbursalDate), "DD MMM, YYYY");
const allocationDate = dateFormat(new Date(caseDetail.allocatedAt), "DD MMM, YYYY");
const disbursalDate = dateFormat(
new Date(loanDetails.disbursalDate),
'DD MMM, YYYY',
);
const allocationDate = dateFormat(
new Date(caseDetail.allocatedAt),
'DD MMM, YYYY',
);
const [openImage, setOpenImage] = useState<boolean>(false);
@@ -36,36 +47,37 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
return (
<View style={[GenericStyles.row, GenericStyles.pb16, styles.container]}>
<View style={[styles.avatarContainer]}>
<Pressable onPress={handleOpenClose}>
<Avatar
size={60}
name={customerInfo.customerName}
dataURI={customerInfo.imageURL}
/>
</Pressable>
</View>
<Pressable onPress={handleOpenClose}>
<Avatar
size={64}
name={customerInfo.customerName}
dataURI={customerInfo.imageURL}
/>
</Pressable>
<View style={[styles.infoContainer]}>
<Heading dark type="h4">
<Heading dark type="h3">
{customerInfo.customerName}
</Heading>
<View style={[GenericStyles.row, GenericStyles.mb8]}>
<View style={[GenericStyles.row, GenericStyles.mb8, GenericStyles.mt4]}>
<IconLabel
icon={<DocumentIcon />}
text={LoanTypeUIMapping[loanDetails.loanType]}
/>
<IconLabel
containerStyle={GenericStyles.ml10}
text={LoanAccountStatusUIMapping[loanDetails.loanAccountStatus]}
text={
LoanAccountStatusUIMapping[
loanDetails.loanAccountStatus
]
}
/>
</View>
<View style={[GenericStyles.row, GenericStyles.mb8]}>
<IconLabel icon={<CalenderIcon />} text={disbursalDate} />
<IconLabel
icon={<CalenderIcon />}
text={disbursalDate}
/>
<IconLabel
text={`${loanDetails.tenureMonths} ${loanDetails.tenureMonths > 1 ? "Months" : "Month"}`}
text={`${loanDetails.tenureMonths} ${
loanDetails.tenureMonths > 1 ? 'Months' : 'Month'
}`}
containerStyle={GenericStyles.ml10}
/>
</View>
@@ -75,7 +87,10 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
</Text>
</View>
</View>
<Modal animationType={'slide'} visible={openImage} onRequestClose={handleOpenClose}>
<Modal
animationType={'slide'}
visible={openImage}
onRequestClose={handleOpenClose}>
<SafeAreaView
style={[
GenericStyles.fill,
@@ -90,13 +105,10 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
style={[
GenericStyles.fill,
GenericStyles.alignCenter,
GenericStyles.row
GenericStyles.row,
]}>
<Image
style={[
GenericStyles.fill,
styles.imageStyle,
]}
style={[GenericStyles.fill, styles.imageStyle]}
source={{uri: customerInfo.imageURL}}
resizeMode={'contain'}
/>
@@ -108,24 +120,19 @@ const UserDetailsSection: React.FC<IUserDetailsSection> = props => {
};
const styles = StyleSheet.create({
avatarContainer: {
height: 60,
width: 60,
flex: 0.2,
},
container: {
borderBottomWidth: 1,
borderBottomColor: COLORS.BORDER.PRIMARY,
},
infoContainer: {
flex: 0.6,
marginLeft: 16,
},
imageStyle:{
height: 300
imageStyle: {
height: 300,
},
backgroundColor: {
backgroundColor: COLORS.BACKGROUND.HEADER,
},
backgroundColor:{
backgroundColor: COLORS.BACKGROUND.HEADER
}
});
export default UserDetailsSection;

View File

@@ -47,7 +47,7 @@ const PhoneNumberSelectionBottomSheet: React.FC<
styles.bottomSheetHeader,
]}>
<Heading dark type="h5">
Customer's Number
Customer's numbers
</Heading>
<TouchableOpacity
activeOpacity={0.7}
@@ -82,6 +82,7 @@ const PhoneNumberSelectionBottomSheet: React.FC<
setShowPhoneNumberBottomSheet(prev => !prev);
setShowCallingBottomSheet(prev => !prev);
}}
disabled={!selectedPhoneNumber}
/>
</View>
</View>

View File

@@ -1,8 +1,9 @@
import {Linking, View} from 'react-native';
import {Linking, StyleSheet, View} from 'react-native';
import Text from '../../../../RN-UI-LIB/src/components/Text';
import {GenericStyles} from '../../../../RN-UI-LIB/src/styles';
import Button from '../../../../RN-UI-LIB/src/components/Button';
import React from 'react';
import MapPinIcon from '../../../../RN-UI-LIB/src/Icons/MapPinIcon';
const TaskContent = ({
address,
@@ -24,16 +25,27 @@ const TaskContent = ({
<View style={[GenericStyles.row]}>
{geolocationUrl && (
<Button
style={{marginRight: 10}}
style={styles.geolocationBtn}
variant="secondary"
onPress={openGeolocation}
title="Open in maps"
title="Open map"
leftIcon={<MapPinIcon />}
/>
)}
<Button title="Add Feedback" />
<Button title="Add feedback" style={styles.feedbackBtn} />
</View>
</View>
);
};
const styles = StyleSheet.create({
geolocationBtn: {
width: 124,
marginRight: 10,
},
feedbackBtn: {
width: 150,
},
});
export default TaskContent;

View File

@@ -10,6 +10,7 @@ import PhoneNumberSelectionBottomSheet from './PhoneNumberSelectionBottomSheet';
import TaskContent from './TaskContent';
import StepperHeader, {STEPPER_STATE} from './StepperHeader';
import { navigateToScreen } from '../../../components/utlis/navigationUtlis';
import Heading from '../../../../RN-UI-LIB/src/components/Heading';
interface IStepperContent {
content?: React.ReactNode;
@@ -35,16 +36,26 @@ const TaskStepper: React.FC<ITaskStepper> = porps => {
React.useState(false);
const [showCallingBottomSheet, setShowCallingBottomSheet] =
React.useState(false);
const {tasks, context, mobileNumbers} = useSelector((state: RootState) => ({
const {tasks, context, mobileNumbers = []} = useSelector((state: RootState) => ({
mobileNumbers: state.case.customerInfo.mobileNumbers,
tasks: state.case.tasks,
context: state.case.context,
}));
const [selectedPhoneNumber, setSelectedPhoneNumber] = React.useState('');
const handleCustomerCall = () => {
if(mobileNumbers?.length > 0) {
setShowPhoneNumberBottomSheet(true)
return;
}
setSelectedPhoneNumber(mobileNumbers[0]);
setShowCallingBottomSheet(true)
}
return (
<>
<View style={[GenericStyles.p16]}>
<Heading type='h3' style={styles.header} dark bold>Addresses</Heading>
{tasks.map((task, index) => {
const verdict =
// @ts-ignore
@@ -107,9 +118,9 @@ const TaskStepper: React.FC<ITaskStepper> = porps => {
<View style={[GenericStyles.row, styles.journeyContainer]}>
<Button
style={[styles.callCustomerButton]}
title="Call Customer"
title="Call customer"
variant="secondary"
onPress={() => setShowPhoneNumberBottomSheet(true)}
onPress={handleCustomerCall}
/>
</View>
<PhoneNumberSelectionBottomSheet
@@ -130,9 +141,13 @@ const TaskStepper: React.FC<ITaskStepper> = porps => {
};
export const styles = StyleSheet.create({
header: {
marginBottom: 18
},
journeyContainer: {
borderTopWidth: 1,
borderTopColor: COLORS.BORDER.PRIMARY,
borderStyle: 'dashed'
},
stepperCurrent: {
height: PixelRatio.roundToNearestPixel(32),
@@ -184,13 +199,10 @@ export const styles = StyleSheet.create({
paddingLeft: 28.5,
},
bottomSheetHeader: {
borderBottomWidth: 1,
borderBottomColor: COLORS.BORDER.PRIMARY,
paddingBottom: 20,
},
phoneNumberSelectionSection: {
paddingBottom: 30,
// height: 170,
},
bottomSheetButton: {
position: 'absolute',