NTP-47538 | all feedback details screen code refactor (#1116)
This commit is contained in:
committed by
GitHub
parent
c62c632a84
commit
de36a46765
@@ -113,8 +113,8 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
|
||||
def VERSION_CODE = 247
|
||||
def VERSION_NAME = "2.18.4"
|
||||
def VERSION_CODE = 249
|
||||
def VERSION_NAME = "2.18.6"
|
||||
|
||||
android {
|
||||
namespace "com.avapp"
|
||||
|
||||
@@ -1 +1 @@
|
||||
248
|
||||
249
|
||||
@@ -1 +1 @@
|
||||
2.18.5
|
||||
2.18.6
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "AV_APP",
|
||||
"version": "2.18.4",
|
||||
"buildNumber": "247",
|
||||
"version": "2.18.6",
|
||||
"buildNumber": "249",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"android:dev": "yarn move:dev && react-native run-android",
|
||||
|
||||
@@ -9,7 +9,7 @@ interface IPastFeedbacksPayload {
|
||||
page_size: number;
|
||||
customerRecahble: boolean;
|
||||
addressReferenceIds?: string; // required to fetch past feedback on addresses
|
||||
isGeolocationFeedback: boolean;
|
||||
isGeolocationFeedback?: boolean;
|
||||
}
|
||||
|
||||
export interface IFilterPayload {
|
||||
|
||||
@@ -1,10 +1,7 @@
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { Modal, RefreshControl, ScrollView, StyleSheet, View } from 'react-native';
|
||||
import Accordion from '../../../../RN-UI-LIB/src/components/accordian/Accordian';
|
||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { RefreshControl, ScrollView, View } from 'react-native';
|
||||
import NavigationHeader from '../../../../RN-UI-LIB/src/components/NavigationHeader';
|
||||
import Text from '../../../../RN-UI-LIB/src/components/Text';
|
||||
import { GenericStyles, SCREEN_HEIGHT, getShadowStyle } from '../../../../RN-UI-LIB/src/styles';
|
||||
import { COLORS } from '../../../../RN-UI-LIB/src/styles/colors';
|
||||
import { GenericStyles } from '../../../../RN-UI-LIB/src/styles';
|
||||
import {
|
||||
IFilterPayload,
|
||||
getPastFeedbacks,
|
||||
@@ -15,10 +12,7 @@ import { logError } from '../../../components/utlis/errorUtils';
|
||||
import { goBack } from '../../../components/utlis/navigationUtlis';
|
||||
import { useAppDispatch, useAppSelector } from '../../../hooks';
|
||||
import useIsOnline from '../../../hooks/useIsOnline';
|
||||
import { RootState } from '../../../store/store';
|
||||
import { IFeedback } from '../../../types/feedback.types';
|
||||
import FeedbackDetailAnswerContainer from './FeedbackDetailAnswerContainer';
|
||||
import FeedbackDetailItem from './FeedbackDetailItem';
|
||||
import { addClickstreamEvent } from '../../../services/clickstreamEventService';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '../../../common/Constants';
|
||||
import Pagination from '../../../../RN-UI-LIB/src/components/pagination/Pagination';
|
||||
@@ -28,47 +22,17 @@ import { ToastMessages } from './../../../screens/allCases/constants';
|
||||
import { setFeedbackHistoryLoading } from '../../../reducer/feedbackHistorySlice';
|
||||
import SuspenseLoader from '../../../../RN-UI-LIB/src/components/suspense_loader/SuspenseLoader';
|
||||
import LineLoader from '../../../../RN-UI-LIB/src/components/suspense_loader/LineLoader';
|
||||
import NoPastFeedbackIcon from '../../../assets/icons/NoPastFeedbackIcon';
|
||||
import Button from '../../../../RN-UI-LIB/src/components/Button';
|
||||
import FilterIcon from '../../../assets/icons/FilterIcon';
|
||||
import Filters, { TFilterOptions } from '../../../components/filters/Filters';
|
||||
import { _map } from '../../../../RN-UI-LIB/src/utlis/common';
|
||||
import ChevronDown from '../../../assets/icons/ChevronDown';
|
||||
import ChevronUp from '../../../assets/icons/ChevronUp';
|
||||
import { TFilterOptions } from '../../../components/filters/Filters';
|
||||
import { PAST_FEEDBACK_PAGE_SIZE } from '@screens/caseDetails/feedback/pastFeedbackCommon';
|
||||
|
||||
const FEEDBACK_PAGE_TITLE = 'All feedbacks';
|
||||
const ADDRESS_FEEDBACK_PAGE_TITLE = 'Address feedback';
|
||||
|
||||
const SCROLL_LAYOUT_OFFSET = 10;
|
||||
|
||||
interface IFeedbackDetailContainer {
|
||||
route: {
|
||||
params: {
|
||||
loanAccountNumber: string;
|
||||
addressReferenceIds?: string;
|
||||
addressText?: string;
|
||||
activeFeedbackReferenceId?: string;
|
||||
caseId: string;
|
||||
pageNo?: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const getFiltersPayload = (selectedFilters: TFilterOptions) => {
|
||||
const payload: IFilterPayload = { filters: [] };
|
||||
_map(selectedFilters, (filterName: string) => {
|
||||
const filter = selectedFilters[filterName];
|
||||
if (!filter || !filter.filters) {
|
||||
return;
|
||||
}
|
||||
payload.filters.push({
|
||||
filterName,
|
||||
selectedValue: Object.keys(filter.filters),
|
||||
});
|
||||
});
|
||||
return payload;
|
||||
};
|
||||
import { IFeedbackDetailContainer } from './types';
|
||||
import {
|
||||
ADDRESS_FEEDBACK_PAGE_TITLE,
|
||||
FEEDBACK_PAGE_TITLE,
|
||||
getFiltersPayload,
|
||||
handlePageChangeClickstream,
|
||||
} from './utils';
|
||||
import FeedbackListComponent from './FeedbackListComponent';
|
||||
import FeedbackFilters from './FeedbackFilters';
|
||||
|
||||
const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: routeParams }) => {
|
||||
const {
|
||||
@@ -83,30 +47,24 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
} = routeParams;
|
||||
|
||||
const isPastFeedbackOnAddress = addressText || addressReferenceIds?.length;
|
||||
|
||||
const [isExpanded, setIsExpanded] = useState<boolean>(false);
|
||||
const [feedbackFilters, setFeedbackFilters] = useState<TFilterOptions>({});
|
||||
const isOnline = useIsOnline();
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const { feedbackListFromCache, feedbackTotalPages, feedbackFiltersTemplate } = useAppSelector(
|
||||
(state: RootState) => ({
|
||||
feedbackListFromCache: state.feedbackHistory?.[loanAccountNumber as string]?.data || [],
|
||||
feedbackTotalPages: state.feedbackHistory?.[loanAccountNumber as string]?.totalPages || 0,
|
||||
feedbackFiltersTemplate: state.feedbackFilters?.feedbackFiltersTemplate || {},
|
||||
})
|
||||
const feedbackListFromCache = useAppSelector(
|
||||
(state) => state.feedbackHistory?.[loanAccountNumber as string]?.data || []
|
||||
);
|
||||
const feedbackTotalPages = useAppSelector(
|
||||
(state) => state.feedbackHistory?.[loanAccountNumber as string]?.totalPages || 0
|
||||
);
|
||||
|
||||
const [feedbackList, setFeedbackList] = useState<IFeedback[]>(
|
||||
!isPastFeedbackOnAddress ? feedbackListFromCache : []
|
||||
);
|
||||
const [totalPage, setTotalPage] = useState(!isPastFeedbackOnAddress ? feedbackTotalPages : 0);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [currentPage, setCurrentPage] = useState(pageNo);
|
||||
const [dataSourceCord, setDataSourceCord] = useState(0);
|
||||
const ref = useRef();
|
||||
const [showFilterModal, setShowFilterModal] = useState(false);
|
||||
|
||||
const fetchFeedbacks = useCallback(
|
||||
(filtersPayload: IFilterPayload) => {
|
||||
@@ -114,11 +72,6 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
? getPastFeedbacksOnAddresses
|
||||
: getPastFeedbacks;
|
||||
|
||||
if (isPastFeedbackOnAddress) {
|
||||
dispatch(
|
||||
setFeedbackHistoryLoading({ loanAccountNumbers: [loanAccountNumber], isLoading: true })
|
||||
);
|
||||
}
|
||||
getPastFeedbackApiFn(
|
||||
{
|
||||
loan_account_number: loanAccountNumber,
|
||||
@@ -173,7 +126,7 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
|
||||
useEffect(() => {
|
||||
setCurrentPage(pageNo ?? 1);
|
||||
}, [pageNo])
|
||||
}, [pageNo]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isPastFeedbackOnAddress) {
|
||||
@@ -203,16 +156,6 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
setCurrentPage(page);
|
||||
};
|
||||
|
||||
const handlePageChangeClickstream = (
|
||||
page: number,
|
||||
eventName: { name: string; description: string }
|
||||
) => {
|
||||
addClickstreamEvent(eventName, {
|
||||
currentPageNumber: page,
|
||||
lan: loanAccountNumber,
|
||||
});
|
||||
};
|
||||
|
||||
const handleFilterChange = (filters: TFilterOptions) => {
|
||||
const filtersPayload = getFiltersPayload(filters);
|
||||
if (currentPage === 1) {
|
||||
@@ -224,8 +167,6 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
setFeedbackFilters(filters);
|
||||
};
|
||||
|
||||
const feedbackFilterCount = Object.keys(feedbackFilters)?.length;
|
||||
|
||||
return (
|
||||
<Layout>
|
||||
<View style={[GenericStyles.fill, GenericStyles.whiteBackground]}>
|
||||
@@ -233,32 +174,11 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
title={!isPastFeedbackOnAddress ? FEEDBACK_PAGE_TITLE : ADDRESS_FEEDBACK_PAGE_TITLE}
|
||||
onBack={goBack}
|
||||
/>
|
||||
{!isPastFeedbackOnAddress ? (
|
||||
<View style={[GenericStyles.mlAuto, GenericStyles.pv12, GenericStyles.ph16]}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
leftIcon={
|
||||
<View style={GenericStyles.mr12}>
|
||||
<FilterIcon
|
||||
fillColor={feedbackFilterCount ? COLORS.TEXT.BLUE : COLORS.BACKGROUND.LIGHT}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
style={getShadowStyle(2)}
|
||||
title="Filters"
|
||||
buttonStyle={[GenericStyles.ph12, GenericStyles.pv8]}
|
||||
onPress={() => setShowFilterModal(true)}
|
||||
/>
|
||||
{feedbackFilterCount ? (
|
||||
<View style={[styles.filterCount]}>
|
||||
<Text style={[GenericStyles.whiteText, { marginTop: -3 }]} small bold>
|
||||
{feedbackFilterCount}
|
||||
</Text>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
) : null}
|
||||
|
||||
<FeedbackFilters
|
||||
isPastFeedbackOnAddress={isPastFeedbackOnAddress}
|
||||
feedbackFilters={feedbackFilters}
|
||||
handleFilterChange={handleFilterChange}
|
||||
/>
|
||||
<ScrollView
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
@@ -286,80 +206,15 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
</>
|
||||
}
|
||||
>
|
||||
{feedbackList?.length ? (
|
||||
<>
|
||||
{isPastFeedbackOnAddress ? (
|
||||
<View style={styles.addressCard}>
|
||||
<Text style={[styles.addressText, { color: COLORS.TEXT.LIGHT }]}>
|
||||
Feedback for
|
||||
</Text>
|
||||
<Text style={[styles.addressText, { color: COLORS.TEXT.DARK }]}>
|
||||
{addressText}
|
||||
</Text>
|
||||
</View>
|
||||
) : null}
|
||||
{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.br8,
|
||||
getShadowStyle(4),
|
||||
GenericStyles.ph0,
|
||||
GenericStyles.overflowHidden,
|
||||
GenericStyles.ph16,
|
||||
styles.accordianPadding,
|
||||
]}
|
||||
isActive={feedback.referenceId === activeFeedbackReferenceId}
|
||||
touchableDelay={50}
|
||||
touchableOpacity={0.8}
|
||||
accordionHeader={
|
||||
<FeedbackDetailItem
|
||||
key={feedback.referenceId}
|
||||
feedbackItem={feedback}
|
||||
isExpanded={isExpanded}
|
||||
caseId={caseId}
|
||||
/>
|
||||
}
|
||||
customExpandUi={{
|
||||
whenCollapsed: <ChevronDown />,
|
||||
whenExpanded: <ChevronUp />,
|
||||
}}
|
||||
onExpanded={(value) => {
|
||||
setIsExpanded(value);
|
||||
}}
|
||||
>
|
||||
<FeedbackDetailAnswerContainer
|
||||
feedbackDetails={feedback}
|
||||
activeFeedbackReferenceId={feedback.referenceId}
|
||||
loanAccountNumber={loanAccountNumber}
|
||||
/>
|
||||
</Accordion>
|
||||
</View>
|
||||
))}
|
||||
</>
|
||||
) : (
|
||||
<View
|
||||
style={[
|
||||
styles.noFeedbackContainer,
|
||||
GenericStyles.centerAligned,
|
||||
GenericStyles.columnDirection,
|
||||
GenericStyles.fill,
|
||||
]}
|
||||
>
|
||||
<NoPastFeedbackIcon />
|
||||
<Text style={[styles.textContainer, styles.noFeedbackText]}>
|
||||
No previous feedback found
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
<FeedbackListComponent
|
||||
feedbackList={feedbackList}
|
||||
isPastFeedbackOnAddress={isPastFeedbackOnAddress}
|
||||
addressText={addressText}
|
||||
dataSourceCord={dataSourceCord}
|
||||
activeFeedbackReferenceId={activeFeedbackReferenceId}
|
||||
setDataSourceCord={setDataSourceCord}
|
||||
caseId={caseId}
|
||||
/>
|
||||
</SuspenseLoader>
|
||||
</ScrollView>
|
||||
{feedbackList?.length && totalPage > 1 && !loading ? (
|
||||
@@ -370,97 +225,36 @@ const FeedbackDetailContainer: React.FC<IFeedbackDetailContainer> = ({ route: ro
|
||||
onNextPage={(page) =>
|
||||
handlePageChangeClickstream(
|
||||
page,
|
||||
CLICKSTREAM_EVENT_NAMES.FA_VIEW_PAST_FEEDBACK_NEXT_PAGE_CLICKED
|
||||
CLICKSTREAM_EVENT_NAMES.FA_VIEW_PAST_FEEDBACK_NEXT_PAGE_CLICKED,
|
||||
loanAccountNumber
|
||||
)
|
||||
}
|
||||
onPrevPage={(page) =>
|
||||
handlePageChangeClickstream(
|
||||
page,
|
||||
CLICKSTREAM_EVENT_NAMES.FA_VIEW_PAST_FEEDBACK_PREV_PAGE_CLICKED
|
||||
CLICKSTREAM_EVENT_NAMES.FA_VIEW_PAST_FEEDBACK_PREV_PAGE_CLICKED,
|
||||
loanAccountNumber
|
||||
)
|
||||
}
|
||||
onFirstPage={(page) =>
|
||||
handlePageChangeClickstream(
|
||||
page,
|
||||
CLICKSTREAM_EVENT_NAMES.FA_VIEW_PAST_FEEDBACK_FIRST_PAGE_CLICKED
|
||||
CLICKSTREAM_EVENT_NAMES.FA_VIEW_PAST_FEEDBACK_FIRST_PAGE_CLICKED,
|
||||
loanAccountNumber
|
||||
)
|
||||
}
|
||||
onLastPage={(page) =>
|
||||
handlePageChangeClickstream(
|
||||
page,
|
||||
CLICKSTREAM_EVENT_NAMES.FA_VIEW_PAST_FEEDBACK_LAST_PAGE_CLICKED
|
||||
CLICKSTREAM_EVENT_NAMES.FA_VIEW_PAST_FEEDBACK_LAST_PAGE_CLICKED,
|
||||
loanAccountNumber
|
||||
)
|
||||
}
|
||||
/>
|
||||
) : null}
|
||||
{!isPastFeedbackOnAddress ? (
|
||||
<Modal
|
||||
animationType="slide"
|
||||
animated
|
||||
onRequestClose={() => {
|
||||
setShowFilterModal((prev) => !prev);
|
||||
}}
|
||||
visible={showFilterModal}
|
||||
>
|
||||
<Filters
|
||||
header="Feedback Filters"
|
||||
defaultSelectedFilters={feedbackFilters}
|
||||
closeFilterModal={() => setShowFilterModal((prev) => !prev)}
|
||||
filters={feedbackFiltersTemplate}
|
||||
onFilterChange={handleFilterChange}
|
||||
/>
|
||||
</Modal>
|
||||
) : null}
|
||||
</View>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
addressCard: {
|
||||
padding: 16,
|
||||
borderRadius: 8,
|
||||
marginTop: 16,
|
||||
marginBottom: 12,
|
||||
backgroundColor: COLORS.BACKGROUND.SILVER,
|
||||
},
|
||||
addressText: {
|
||||
fontWeight: '400',
|
||||
fontSize: 12,
|
||||
lineHeight: 18,
|
||||
},
|
||||
textContainer: {
|
||||
fontSize: 16,
|
||||
lineHeight: 24,
|
||||
},
|
||||
noFeedbackText: {
|
||||
color: COLORS.TEXT.GREY_32465B,
|
||||
fontWeight: '500',
|
||||
},
|
||||
noFeedbackContainer: {
|
||||
marginTop: '50%',
|
||||
},
|
||||
accordionExpandBtn: {
|
||||
fontSize: 13,
|
||||
fontWeight: '500',
|
||||
lineHeight: 20,
|
||||
color: COLORS.TEXT.BLUE,
|
||||
},
|
||||
filterCount: {
|
||||
backgroundColor: COLORS.TEXT.BLUE,
|
||||
width: 18,
|
||||
height: 18,
|
||||
borderRadius: 9,
|
||||
alignItems: 'center',
|
||||
position: 'absolute',
|
||||
opacity: 0.8,
|
||||
top: 7,
|
||||
right: 11,
|
||||
},
|
||||
accordianPadding: {
|
||||
paddingTop: 16,
|
||||
paddingBottom: 8,
|
||||
},
|
||||
});
|
||||
|
||||
export default FeedbackDetailContainer;
|
||||
|
||||
@@ -164,7 +164,7 @@ const FeedbackDetailItem = ({
|
||||
}
|
||||
style={[GenericStyles.row, styles.BtnPadding]}
|
||||
>
|
||||
<Text style={[styles.textContainer, styles.geolocationBtn]}>Open map</Text>
|
||||
<Text style={[styles.textContainer, styles.geolocationBtn]}>Feedback location</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
hitSlop={{ top: 20, bottom: 20, left: 20, right: 20 }}
|
||||
|
||||
83
src/screens/caseDetails/feedback/FeedbackFilters.tsx
Normal file
83
src/screens/caseDetails/feedback/FeedbackFilters.tsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import { Modal, View, StyleSheet } from 'react-native';
|
||||
import Button from '../../../../RN-UI-LIB/src/components/Button';
|
||||
import FilterIcon from '../../../assets/icons/FilterIcon';
|
||||
import Filters from '../../../components/filters/Filters';
|
||||
import { COLORS } from '@rn-ui-lib/colors';
|
||||
import Text from '../../../../RN-UI-LIB/src/components/Text';
|
||||
import { GenericStyles, getShadowStyle } from '../../../../RN-UI-LIB/src/styles';
|
||||
import { useAppSelector } from '../../../hooks';
|
||||
import { useState } from 'react';
|
||||
import { IFeedbackFilters } from './types';
|
||||
|
||||
const FeedbackFilters = (props: IFeedbackFilters) => {
|
||||
const { isPastFeedbackOnAddress, feedbackFilters, handleFilterChange } = props;
|
||||
const feedbackFiltersTemplate = useAppSelector(
|
||||
(state) => state.feedbackFilters?.feedbackFiltersTemplate || {}
|
||||
);
|
||||
const feedbackFilterCount = Object.keys(feedbackFilters)?.length;
|
||||
if (isPastFeedbackOnAddress) {
|
||||
return null;
|
||||
}
|
||||
const [showFilterModal, setShowFilterModal] = useState(false);
|
||||
const handleFiltersButtonClick = () => {
|
||||
setShowFilterModal(!showFilterModal);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={[GenericStyles.mlAuto, GenericStyles.pv12, GenericStyles.ph16]}>
|
||||
<Button
|
||||
variant="secondary"
|
||||
leftIcon={
|
||||
<View style={GenericStyles.mr12}>
|
||||
<FilterIcon
|
||||
fillColor={feedbackFilterCount ? COLORS.TEXT.BLUE : COLORS.BACKGROUND.LIGHT}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
style={getShadowStyle(2)}
|
||||
title="Filters"
|
||||
buttonStyle={[GenericStyles.ph12, GenericStyles.pv8]}
|
||||
onPress={handleFiltersButtonClick}
|
||||
/>
|
||||
{feedbackFilterCount ? (
|
||||
<View style={[styles.filterCount]}>
|
||||
<Text style={[GenericStyles.whiteText, styles.marginTop]} small bold>
|
||||
{feedbackFilterCount}
|
||||
</Text>
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
<Modal
|
||||
animationType="slide"
|
||||
animated
|
||||
onRequestClose={handleFiltersButtonClick}
|
||||
visible={showFilterModal}
|
||||
>
|
||||
<Filters
|
||||
header="Feedback Filters"
|
||||
defaultSelectedFilters={feedbackFilters}
|
||||
closeFilterModal={handleFiltersButtonClick}
|
||||
filters={feedbackFiltersTemplate}
|
||||
onFilterChange={handleFilterChange}
|
||||
/>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
filterCount: {
|
||||
backgroundColor: COLORS.TEXT.BLUE,
|
||||
width: 18,
|
||||
height: 18,
|
||||
borderRadius: 9,
|
||||
alignItems: 'center',
|
||||
position: 'absolute',
|
||||
opacity: 0.8,
|
||||
top: 7,
|
||||
right: 11,
|
||||
},
|
||||
marginTop: { marginTop: -3 },
|
||||
});
|
||||
export default FeedbackFilters;
|
||||
137
src/screens/caseDetails/feedback/FeedbackListComponent.tsx
Normal file
137
src/screens/caseDetails/feedback/FeedbackListComponent.tsx
Normal file
@@ -0,0 +1,137 @@
|
||||
import { COLORS } from '@rn-ui-lib/colors';
|
||||
import React, { useState } from 'react';
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import FeedbackDetailAnswerContainer from './FeedbackDetailAnswerContainer';
|
||||
import ChevronDown from '@assets/icons/ChevronDown';
|
||||
import ChevronUp from '@assets/icons/ChevronUp';
|
||||
import FeedbackDetailItem from './FeedbackDetailItem';
|
||||
import NoPastFeedbackIcon from '@assets/icons/NoPastFeedbackIcon';
|
||||
import Text from '../../../../RN-UI-LIB/src/components/Text';
|
||||
import { IFeedback } from '../../../types/feedback.types';
|
||||
import Accordion from '@rn-ui-lib/components/accordian/Accordian';
|
||||
import { GenericStyles, getShadowStyle } from '../../../../RN-UI-LIB/src/styles';
|
||||
import { SCROLL_LAYOUT_OFFSET } from './utils';
|
||||
import { IFeedbackListComponentProps } from './types';
|
||||
import { useAppSelector } from '@hooks';
|
||||
|
||||
const FeedbackListComponent = (props: IFeedbackListComponentProps) => {
|
||||
const {
|
||||
feedbackList,
|
||||
isPastFeedbackOnAddress,
|
||||
addressText,
|
||||
dataSourceCord,
|
||||
activeFeedbackReferenceId,
|
||||
setDataSourceCord,
|
||||
caseId,
|
||||
} = props;
|
||||
|
||||
const [isExpanded, setIsExpanded] = useState<boolean>(false);
|
||||
const loanAccountNumber = useAppSelector(
|
||||
(state) => state.allCases.caseDetails[caseId]?.loanAccountNumber
|
||||
);
|
||||
if (!feedbackList?.length)
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
styles.noFeedbackContainer,
|
||||
GenericStyles.centerAligned,
|
||||
GenericStyles.columnDirection,
|
||||
GenericStyles.fill,
|
||||
]}
|
||||
>
|
||||
<NoPastFeedbackIcon />
|
||||
<Text style={[styles.textContainer, styles.noFeedbackText]}>
|
||||
No previous feedback found
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{isPastFeedbackOnAddress ? (
|
||||
<View style={styles.addressCard}>
|
||||
<Text style={[styles.addressText, { color: COLORS.TEXT.LIGHT }]}>Feedback for</Text>
|
||||
<Text style={[styles.addressText, { color: COLORS.TEXT.DARK }]}>{addressText}</Text>
|
||||
</View>
|
||||
) : null}
|
||||
{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.br8,
|
||||
getShadowStyle(4),
|
||||
GenericStyles.ph0,
|
||||
GenericStyles.overflowHidden,
|
||||
GenericStyles.ph16,
|
||||
styles.accordianPadding,
|
||||
]}
|
||||
isActive={feedback.referenceId === activeFeedbackReferenceId}
|
||||
touchableDelay={50}
|
||||
touchableOpacity={0.8}
|
||||
accordionHeader={
|
||||
<FeedbackDetailItem
|
||||
key={feedback.referenceId}
|
||||
feedbackItem={feedback}
|
||||
isExpanded={isExpanded}
|
||||
caseId={caseId}
|
||||
/>
|
||||
}
|
||||
customExpandUi={{
|
||||
whenCollapsed: <ChevronDown />,
|
||||
whenExpanded: <ChevronUp />,
|
||||
}}
|
||||
onExpanded={(value) => {
|
||||
setIsExpanded(value);
|
||||
}}
|
||||
>
|
||||
<FeedbackDetailAnswerContainer
|
||||
feedbackDetails={feedback}
|
||||
activeFeedbackReferenceId={feedback.referenceId}
|
||||
loanAccountNumber={loanAccountNumber}
|
||||
/>
|
||||
</Accordion>
|
||||
</View>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
addressCard: {
|
||||
padding: 16,
|
||||
borderRadius: 8,
|
||||
marginTop: 16,
|
||||
marginBottom: 12,
|
||||
backgroundColor: COLORS.BACKGROUND.SILVER,
|
||||
},
|
||||
addressText: {
|
||||
fontWeight: '400',
|
||||
fontSize: 12,
|
||||
lineHeight: 18,
|
||||
},
|
||||
textContainer: {
|
||||
fontSize: 16,
|
||||
lineHeight: 24,
|
||||
},
|
||||
noFeedbackText: {
|
||||
color: COLORS.TEXT.GREY_32465B,
|
||||
fontWeight: '500',
|
||||
},
|
||||
noFeedbackContainer: {
|
||||
marginTop: '50%',
|
||||
},
|
||||
accordianPadding: {
|
||||
paddingTop: 16,
|
||||
paddingBottom: 8,
|
||||
},
|
||||
});
|
||||
|
||||
export default FeedbackListComponent;
|
||||
@@ -1,3 +1,6 @@
|
||||
import { TFilterOptions } from '@components/filters/Filters';
|
||||
import { IFeedback } from '@interfaces/feedback.types';
|
||||
|
||||
export const TOP_FEEDBACK_MAP: { [key: number]: string } = {
|
||||
0: 'Current month status',
|
||||
1: 'Last month status',
|
||||
@@ -7,3 +10,32 @@ export interface IFeedbackLoading {
|
||||
isTopFeedbackItem?: boolean;
|
||||
arrayLength?: number;
|
||||
}
|
||||
|
||||
export interface IFeedbackDetailContainer {
|
||||
route: {
|
||||
params: {
|
||||
loanAccountNumber: string;
|
||||
addressReferenceIds?: string;
|
||||
addressText?: string;
|
||||
activeFeedbackReferenceId?: string;
|
||||
caseId: string;
|
||||
pageNo?: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface IFeedbackListComponentProps {
|
||||
feedbackList: IFeedback[];
|
||||
isPastFeedbackOnAddress: string | number | undefined;
|
||||
addressText: string | undefined;
|
||||
dataSourceCord: number;
|
||||
activeFeedbackReferenceId: string | undefined;
|
||||
setDataSourceCord: React.Dispatch<React.SetStateAction<number>>;
|
||||
caseId: string;
|
||||
}
|
||||
|
||||
export interface IFeedbackFilters {
|
||||
isPastFeedbackOnAddress: string | number | undefined;
|
||||
feedbackFilters: TFilterOptions;
|
||||
handleFilterChange: (filters: TFilterOptions) => void;
|
||||
}
|
||||
|
||||
34
src/screens/caseDetails/feedback/utils.tsx
Normal file
34
src/screens/caseDetails/feedback/utils.tsx
Normal file
@@ -0,0 +1,34 @@
|
||||
import { IFilterPayload } from "@actions/feedbackActions";
|
||||
import { TFilterOptions } from "@components/filters/Filters";
|
||||
import { _map } from "@rn-ui-lib/utils/common";
|
||||
import { addClickstreamEvent } from "@services/clickstreamEventService";
|
||||
|
||||
export const FEEDBACK_PAGE_TITLE = 'All feedbacks';
|
||||
export const ADDRESS_FEEDBACK_PAGE_TITLE = 'Address feedback';
|
||||
export const SCROLL_LAYOUT_OFFSET = 10;
|
||||
|
||||
export const getFiltersPayload = (selectedFilters: TFilterOptions) => {
|
||||
const payload: IFilterPayload = { filters: [] };
|
||||
_map(selectedFilters, (filterName: string) => {
|
||||
const filter = selectedFilters[filterName];
|
||||
if (!filter || !filter.filters) {
|
||||
return;
|
||||
}
|
||||
payload.filters.push({
|
||||
filterName,
|
||||
selectedValue: Object.keys(filter.filters),
|
||||
});
|
||||
});
|
||||
return payload;
|
||||
};
|
||||
|
||||
export const handlePageChangeClickstream = (
|
||||
page: number,
|
||||
eventName: { name: string; description: string },
|
||||
loanAccountNumber: string
|
||||
) => {
|
||||
addClickstreamEvent(eventName, {
|
||||
currentPageNumber: page,
|
||||
lan: loanAccountNumber,
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user