TP-20465 | Detail page fixes (#159)
This commit is contained in:
committed by
GitHub Enterprise
parent
11af3d2a5f
commit
11ae25b2ad
Submodule RN-UI-LIB updated: 5bc9ceccea...9b83ba94da
@@ -18,6 +18,7 @@ import {
|
||||
} from '../reducer/repaymentsSlice';
|
||||
import { AxiosResponse } from 'axios';
|
||||
import { setAddresses, setAddressLoading } from '../reducer/addressSlice';
|
||||
import { IFeedback } from '../types/feedback.types';
|
||||
|
||||
// TODO: Need to add respective interfaces instead of any
|
||||
interface IUnifiedData {
|
||||
@@ -81,8 +82,9 @@ const setUnifiedData =
|
||||
);
|
||||
}
|
||||
if (queryParams[UnifiedCaseDetailsTypes.FEEDBACKS]) {
|
||||
// todo: data is coming as feedback.data
|
||||
dispatch(
|
||||
setFeedbackHistory({ loanAccountNumber, feedbacks }),
|
||||
setFeedbackHistory({ loanAccountNumber, feedbacks: feedbacks?.data as IFeedback[] }),
|
||||
);
|
||||
}
|
||||
if (queryParams[UnifiedCaseDetailsTypes.REPAYMENTS]) {
|
||||
@@ -113,7 +115,7 @@ export const getCaseUnifiedData =
|
||||
const promise = axiosInstance.get(url);
|
||||
promisesList.push(promise);
|
||||
});
|
||||
Promise.allSettled(promisesList).then(res => {
|
||||
Promise.allSettled?.(promisesList).then(res => {
|
||||
dispatch(setUnifiedData(queryParams, loanAccountNumbers, res));
|
||||
}).finally(() => {
|
||||
dispatch(setEmiScheduleLoading({isLoading:false, loanAccountNumbers}));
|
||||
|
||||
@@ -5,22 +5,22 @@ import axiosInstance, {
|
||||
import { logError } from '../components/utlis/errorUtils';
|
||||
|
||||
interface IPastFeedbacks {
|
||||
account_number: string,
|
||||
page_no: number,
|
||||
page_size: number,
|
||||
customerRecahble: boolean,
|
||||
loan_account_number: string,
|
||||
page_no: number,
|
||||
page_size: number,
|
||||
customerRecahble: boolean,
|
||||
}
|
||||
|
||||
export const getPastFeedbacks =
|
||||
(queryParamsPayload: IPastFeedbacks) => {
|
||||
const url = getApiUrl(ApiKeys.PAST_FEEDBACK);
|
||||
return axiosInstance
|
||||
.post(url, {}, {
|
||||
.get(url, {
|
||||
params: queryParamsPayload
|
||||
})
|
||||
.then(response => {
|
||||
if (response?.data) {
|
||||
return response.data;
|
||||
if (response?.data?.data?.length) {
|
||||
return response.data.data;
|
||||
}
|
||||
throw response;
|
||||
})
|
||||
|
||||
@@ -46,8 +46,7 @@ API_URLS[ApiKeys.NEW_ADDRESS] = '/addresses';
|
||||
API_URLS[ApiKeys.GET_SIGNED_URL] = '/cases/get-signed-urls';
|
||||
API_URLS[ApiKeys.CASE_UNIFIED_DETAILS] = '/collection-cases/unified-details/{loanAccountNumber}';
|
||||
API_URLS[ApiKeys.EMI_SCHEDULES] = '/collection-cases/emi-schedules';
|
||||
|
||||
API_URLS[ApiKeys.PAST_FEEDBACK] = '/field-app/feedbacks';
|
||||
API_URLS[ApiKeys.PAST_FEEDBACK] = '/feedback';
|
||||
|
||||
export const API_STATUS_CODE = {
|
||||
OK: 200,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||
import { IFeedback } from '../types/feedback.types';
|
||||
|
||||
interface IFeedbackHistoryState {
|
||||
//TODO: update interface of FeedbackHistory instead of any
|
||||
[loanAccountNumber: string] : {data : any, isLoading: boolean, timestamp: string };
|
||||
[loanAccountNumber: string] : { data : IFeedback[], isLoading: boolean, timestamp: string };
|
||||
}
|
||||
|
||||
const initialState: IFeedbackHistoryState = {};
|
||||
|
||||
@@ -33,7 +33,7 @@ const AddressContainer: React.FC<IAddressContainer> = ({addressList}) => {
|
||||
<View>
|
||||
{
|
||||
addressList.map((address: AddressL1Details) => (
|
||||
<Accordion accordionStyle={{paddingVertical: 28}}
|
||||
<Accordion accordionStyle={{paddingVertical: 28, paddingHorizontal: 16 }}
|
||||
accordionHeader={<AddressItem key={address?.addressDTO?.externalReferenceId}
|
||||
addressItem={address?.addressDTO}
|
||||
geoLocationList={address.matchingGeoLocations}
|
||||
|
||||
@@ -98,8 +98,7 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = props => {
|
||||
} = caseDetail;
|
||||
|
||||
const feedbackList: IFeedback[] = useAppSelector(
|
||||
(state: RootState) =>
|
||||
state.feedbackHistory?.data?.[loanAccountNumber as string],
|
||||
(state: RootState) => state.feedbackHistory?.[loanAccountNumber as string]?.data,
|
||||
);
|
||||
|
||||
const [showCallingBottomSheet, setShowCallingBottomSheet] =
|
||||
@@ -416,7 +415,7 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = props => {
|
||||
GenericStyles.pb16,
|
||||
]}>
|
||||
<View style={GenericStyles.row}>
|
||||
<View style={{ flexBasis: '65%' }}>
|
||||
<View style={{ flexBasis: '60%' }}>
|
||||
<Text
|
||||
style={[
|
||||
styles.textContainer,
|
||||
@@ -426,10 +425,10 @@ const CollectionCaseDetails: React.FC<ICaseDetails> = props => {
|
||||
</Text>
|
||||
</View>
|
||||
{feedbackList?.length ? (
|
||||
<View style={[{ flexBasis: '35%' }]}>
|
||||
<View style={[{ flexBasis: '40%' }]}>
|
||||
<TouchableOpacity
|
||||
activeOpacity={0.7}
|
||||
onPress={console.log}
|
||||
onPress={() => handleRouting(PageRouteEnum.PAST_FEEDBACK_DETAIL)}
|
||||
style={GenericStyles.flex20}>
|
||||
<Text
|
||||
style={[
|
||||
|
||||
@@ -1,8 +1,86 @@
|
||||
import React from 'react'
|
||||
import { ImageBackground, StyleSheet, View } from 'react-native'
|
||||
import Text from '../../../../RN-UI-LIB/src/components/Text'
|
||||
import { GenericStyles } from '../../../../RN-UI-LIB/src/styles'
|
||||
import { COLORS } from '../../../../RN-UI-LIB/src/styles/colors'
|
||||
import { BUSINESS_DATE_FORMAT, BUSINESS_TIME_FORMAT, dateFormat } from '../../../../RN-UI-LIB/src/utlis/dates'
|
||||
import { sanitizeString } from '../../../components/utlis/commonFunctions'
|
||||
import { AnswerType, IAnswerView, OPTION_TAG } from '../../../types/feedback.types'
|
||||
|
||||
const getAnswerText = (answer: IAnswerView) => {
|
||||
switch (answer?.answerType) {
|
||||
case AnswerType.OPTIONS:
|
||||
return sanitizeString(answer.optionText);
|
||||
case AnswerType.TEXT:
|
||||
return sanitizeString(answer.inputText);
|
||||
case AnswerType.DATE:
|
||||
return sanitizeString(dateFormat(new Date(answer.inputDate as string), BUSINESS_DATE_FORMAT))
|
||||
case AnswerType.TIME:
|
||||
return sanitizeString(dateFormat(new Date(answer.inputDate as string), BUSINESS_TIME_FORMAT))
|
||||
case AnswerType.AMOUNT:
|
||||
return `₹ ${answer.inputAmount}`;
|
||||
default:
|
||||
return sanitizeString()
|
||||
}
|
||||
}
|
||||
|
||||
interface IFeedbackDetailAnswerContainer {
|
||||
answerList: IAnswerView[]
|
||||
}
|
||||
|
||||
const FeedbackDetailAnswerContainer: React.FC<IFeedbackDetailAnswerContainer> = ({ answerList }) => {
|
||||
const imageAnswerList = answerList.filter(answer => answer.questionTag === OPTION_TAG.IMAGE_UPLOAD);
|
||||
|
||||
export default function FeedbackDetailAnswerContainer() {
|
||||
return (
|
||||
<Text>FeedbackDetailAnswerContainer</Text>
|
||||
<View style={[styles.container]}>
|
||||
{
|
||||
imageAnswerList.map(image => (
|
||||
<ImageBackground
|
||||
style={styles.image}
|
||||
imageStyle={styles.br8}
|
||||
source={{
|
||||
uri: image.inputText,
|
||||
}} />
|
||||
))
|
||||
}
|
||||
{
|
||||
answerList.filter(answer => answer.questionTag !== OPTION_TAG.IMAGE_UPLOAD).map((answerItem) => (
|
||||
<View style={[GenericStyles.row, GenericStyles.spaceBetween, GenericStyles.mv8]}>
|
||||
<Text style={[{ width: '50%' }, styles.textContainer, styles.questionText]}>{
|
||||
(answerItem.questionKey ? answerItem.questionName : answerItem.questionText) || '--'}</Text>
|
||||
<Text style={[styles.textContainer, styles.answerText]}>{getAnswerText(answerItem)}</Text>
|
||||
</View>
|
||||
))
|
||||
}
|
||||
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
padding: 16,
|
||||
backgroundColor: COLORS.TEXT.GREY_LIGHT,
|
||||
},
|
||||
textContainer: {
|
||||
fontSize: 12,
|
||||
lineHeight: 18,
|
||||
fontWeight: '400',
|
||||
},
|
||||
questionText: {
|
||||
color: COLORS.TEXT.LIGHT
|
||||
},
|
||||
answerText: {
|
||||
color: COLORS.TEXT.DARK
|
||||
},
|
||||
br8:{
|
||||
borderRadius: 8
|
||||
},
|
||||
image: {
|
||||
width: '100%',
|
||||
height: 350,
|
||||
resizeMode: 'contain',
|
||||
},
|
||||
});
|
||||
|
||||
export default FeedbackDetailAnswerContainer;
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { ScrollView, StyleSheet, View } from 'react-native';
|
||||
import { Dimensions, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import Accordion from '../../../../RN-UI-LIB/src/components/accordian/Accordian';
|
||||
import FullScreenLoader from '../../../../RN-UI-LIB/src/components/FullScreenLoader';
|
||||
import NavigationHeader from '../../../../RN-UI-LIB/src/components/NavigationHeader';
|
||||
import Text from '../../../../RN-UI-LIB/src/components/Text';
|
||||
import { GenericStyles, getShadowStyle } from '../../../../RN-UI-LIB/src/styles';
|
||||
@@ -17,7 +18,7 @@ import FeedbackDetailAnswerContainer from './FeedbackDetailAnswerContainer';
|
||||
import FeedbackDetailItem from './FeedbackDetailItem';
|
||||
|
||||
const PAGE_TITLE = 'All feedbacks';
|
||||
const SCROLL_LAYOUT_OFFSET = -10;
|
||||
const SCROLL_LAYOUT_OFFSET = 10;
|
||||
|
||||
interface IFeedbackDetailContainer {
|
||||
route: {
|
||||
@@ -35,28 +36,33 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
|
||||
const isOnline = useIsOnline();
|
||||
|
||||
const [feedbackList, setFeedbackList] = useState<IFeedback[]>([]);
|
||||
|
||||
const feedbackListFromCache = useAppSelector(
|
||||
(state: RootState) => state.feedbackHistory?.data?.[loanAccountNumber],
|
||||
(state: RootState) => state.feedbackHistory?.[loanAccountNumber as string]?.data,
|
||||
)
|
||||
|
||||
const [feedbackList, setFeedbackList] = useState<IFeedback[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if(isOnline) {
|
||||
setLoading(true);
|
||||
getPastFeedbacks({
|
||||
account_number: loanAccountNumber,
|
||||
loan_account_number: loanAccountNumber,
|
||||
page_no: 0,
|
||||
page_size: 100,
|
||||
customerRecahble: false,
|
||||
}).then((res: IFeedback[]) => {
|
||||
if (res) {
|
||||
setFeedbackList(res);
|
||||
if (res?.length) {
|
||||
return setFeedbackList(res);
|
||||
}
|
||||
throw res;
|
||||
})
|
||||
.catch(err => {
|
||||
logError(err);
|
||||
setFeedbackList(feedbackListFromCache);
|
||||
logError(err);
|
||||
})
|
||||
.finally(() => {
|
||||
setLoading(false);
|
||||
})
|
||||
} else {
|
||||
setFeedbackList(feedbackListFromCache);
|
||||
@@ -79,45 +85,43 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
|
||||
return (
|
||||
<View>
|
||||
<FullScreenLoader loading={loading} />
|
||||
<NavigationHeader title={PAGE_TITLE} onBack={goBack} />
|
||||
<ScrollView ref={x => setRef(x)}>
|
||||
<View style={styles.container}>
|
||||
{
|
||||
feedbackList.map((feedback: IFeedback, index) => (
|
||||
<View
|
||||
key={index}
|
||||
onLayout={(event) => {
|
||||
const layout = event.nativeEvent.layout;
|
||||
if (!dataSourceCord && feedback.referenceId === activeFeedbackReferenceId) {
|
||||
setDataSourceCord(layout.y + SCROLL_LAYOUT_OFFSET)
|
||||
}
|
||||
}}>
|
||||
<Accordion accordionStyle={[GenericStyles.p16, getShadowStyle(4)]}
|
||||
isActive={feedback.referenceId === activeFeedbackReferenceId}
|
||||
accordionHeader={<FeedbackDetailItem
|
||||
key={feedback.referenceId}
|
||||
feedbackItem={feedback}
|
||||
/>}
|
||||
customExpandUi={{ whenCollapsed: <Text style={styles.accordionExpandBtn}>View more</Text>, whenExpanded: <Text style={styles.accordionExpandBtn}>View less</Text> }}
|
||||
>
|
||||
<View>
|
||||
<FeedbackDetailAnswerContainer />
|
||||
</View>
|
||||
</Accordion>
|
||||
</View>
|
||||
))
|
||||
}
|
||||
</View>
|
||||
</ScrollView>
|
||||
<ScrollView style={styles.container} ref={x => setRef(x)}>
|
||||
{
|
||||
feedbackList.map((feedback: IFeedback, index) => (
|
||||
<View
|
||||
key={index}
|
||||
onLayout={(event) => {
|
||||
const layout = event.nativeEvent.layout;
|
||||
if (!dataSourceCord && feedback.referenceId === activeFeedbackReferenceId) {
|
||||
setDataSourceCord(layout.y + SCROLL_LAYOUT_OFFSET)
|
||||
}
|
||||
}}>
|
||||
<Accordion accordionStyle={[GenericStyles.pv12, getShadowStyle(4)]}
|
||||
isActive={feedback.referenceId === activeFeedbackReferenceId}
|
||||
accordionHeader={<FeedbackDetailItem
|
||||
key={feedback.referenceId}
|
||||
feedbackItem={feedback}
|
||||
/>}
|
||||
customExpandUi={{ whenCollapsed: <Text style={styles.accordionExpandBtn}>View more</Text>, whenExpanded: <Text style={styles.accordionExpandBtn}>View less</Text> }}
|
||||
>
|
||||
<FeedbackDetailAnswerContainer answerList={feedback.answerViews} />
|
||||
</Accordion>
|
||||
</View>
|
||||
))
|
||||
}
|
||||
</ScrollView>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
paddingVertical: 20,
|
||||
paddingTop: 20,
|
||||
paddingHorizontal: 16,
|
||||
backgroundColor: COLORS.BACKGROUND.PRIMARY,
|
||||
height: (Dimensions.get('window').height - 56)
|
||||
},
|
||||
accordionExpandBtn: {
|
||||
fontSize: 13,
|
||||
|
||||
@@ -29,9 +29,9 @@ const FeedbackDetailItem = ({ feedbackItem }: IFeedbackDetailItem) => {
|
||||
const getBottomSheetHeight = getDynamicBottomSheetHeightPercentageFn();
|
||||
|
||||
return (
|
||||
<View style={GenericStyles.columnDirection}>
|
||||
<View style={[GenericStyles.columnDirection, GenericStyles.ph16]}>
|
||||
<Text numberOfLines={1} ellipsizeMode="tail" style={[styles.textContainer, styles.cardBoldTitle, GenericStyles.pb4]}>
|
||||
{sanitizeString(InteractionStatuses[feedbackItem.interactionStatus])}
|
||||
{sanitizeString(feedbackItem.interactionStatus)}
|
||||
</Text>
|
||||
<Text numberOfLines={1} ellipsizeMode="tail" style={[styles.textContainer, styles.cardFooterText, GenericStyles.fontSize12]}>
|
||||
{sanitizeString(dateFormat(new Date(feedbackItem.createdAt), BUSINESS_DATE_FORMAT))}
|
||||
|
||||
@@ -77,7 +77,7 @@ const FeedbackListContainer: React.FC<IFeedbackListContainer> = ({ loanAccountNu
|
||||
const isOnline = useIsOnline();
|
||||
|
||||
const feedbackList: IFeedback[] = useAppSelector(
|
||||
(state: RootState) => state.feedbackHistory?.data?.[loanAccountNumber],
|
||||
(state: RootState) => state.feedbackHistory?.[loanAccountNumber as string]?.data,
|
||||
);
|
||||
|
||||
const handleRetryEvent = () => {
|
||||
|
||||
@@ -40,7 +40,7 @@ const FeedbackListItem: React.FC<IFeedbackListItem> = ({ feedbackItem, loanAccou
|
||||
<View style={{ flexBasis: '95%' }}>
|
||||
<Text
|
||||
style={styles.textHeading}>
|
||||
{sanitizeString(InteractionStatuses[feedbackItem.interactionStatus])}
|
||||
{sanitizeString(feedbackItem.interactionStatus)}
|
||||
</Text>
|
||||
<Text
|
||||
style={styles.subText}>
|
||||
|
||||
@@ -11,18 +11,25 @@ export enum AnswerType {
|
||||
REMINDER = 'REMINDER',
|
||||
}
|
||||
|
||||
export enum OPTION_TAG {
|
||||
COMMENTS = 'COMMENTS',
|
||||
IMAGE_UPLOAD = 'IMAGE_UPLOAD',
|
||||
}
|
||||
|
||||
export interface IAnswerView {
|
||||
interactionId?: number;
|
||||
referenceId?: string;
|
||||
questionReferenceId?: string;
|
||||
questionName?: string;
|
||||
questionText?: string;
|
||||
questionKey?: string;
|
||||
answerType?: AnswerType;
|
||||
optionReferenceId?: string;
|
||||
optionText?: string;
|
||||
inputAmount?: number;
|
||||
inputDate?: string;
|
||||
inputText?: string;
|
||||
questionTag?: OPTION_TAG;
|
||||
}
|
||||
|
||||
export enum FEEDBACK_TYPE {
|
||||
|
||||
Reference in New Issue
Block a user