NTP-55999 | Top 5 addresses changed to List View (#1131)
This commit is contained in:
@@ -113,8 +113,8 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
|
||||
def VERSION_CODE = 255
|
||||
def VERSION_NAME = "2.18.12"
|
||||
def VERSION_CODE = 256
|
||||
def VERSION_NAME = "2.18.13"
|
||||
|
||||
android {
|
||||
namespace "com.avapp"
|
||||
|
||||
@@ -1 +1 @@
|
||||
255
|
||||
256
|
||||
@@ -1 +1 @@
|
||||
2.18.12
|
||||
2.18.13
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "AV_APP",
|
||||
"version": "2.18.12",
|
||||
"buildNumber": "255",
|
||||
"version": "2.18.13",
|
||||
"buildNumber": "256",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"android:dev": "yarn move:dev && react-native run-android",
|
||||
|
||||
@@ -2,13 +2,13 @@ import * as React from 'react';
|
||||
import Svg, { Mask, Rect, G, Path } from 'react-native-svg';
|
||||
|
||||
const CopyOutlineIcon = () => (
|
||||
<Svg width={19} height={18} viewBox="0 0 19 18" fill="none">
|
||||
<Mask id="mask0_4968_87583" maskUnits="userSpaceOnUse" x={0} y={0} width={19} height={18}>
|
||||
<Rect x={0.599609} width={18} height={18} fill="#D9D9D9" />
|
||||
<Svg width={18} height={18} viewBox="0 0 18 18" fill="none">
|
||||
<Mask id="mask0_6612_162082" maskUnits="userSpaceOnUse" x={0} y={0} width={18} height={18}>
|
||||
<Rect width={18} height={18} fill="#D9D9D9" />
|
||||
</Mask>
|
||||
<G mask="url(#mask0_4968_87583)">
|
||||
<G mask="url(#mask0_6612_162082)">
|
||||
<Path
|
||||
d="M4.34961 16.5C3.93711 16.5 3.58386 16.3533 3.28986 16.0597C2.99636 15.7657 2.84961 15.4125 2.84961 15V4.5H4.34961V15H12.5996V16.5H4.34961ZM7.34961 13.5C6.93711 13.5 6.58411 13.3533 6.29061 13.0597C5.99661 12.7657 5.84961 12.4125 5.84961 12V3C5.84961 2.5875 5.99661 2.23425 6.29061 1.94025C6.58411 1.64675 6.93711 1.5 7.34961 1.5H14.0996C14.5121 1.5 14.8654 1.64675 15.1594 1.94025C15.4529 2.23425 15.5996 2.5875 15.5996 3V12C15.5996 12.4125 15.4529 12.7657 15.1594 13.0597C14.8654 13.3533 14.5121 13.5 14.0996 13.5H7.34961ZM7.34961 12H14.0996V3H7.34961V12Z"
|
||||
d="M6.5 18C6.0875 18 5.73425 17.8533 5.44025 17.5598C5.14675 17.2658 5 16.9125 5 16.5V6H6.5V16.5H14.75V18H6.5ZM9.5 15C9.0875 15 8.7345 14.8533 8.441 14.5598C8.147 14.2658 8 13.9125 8 13.5V4.5C8 4.0875 8.147 3.73425 8.441 3.44025C8.7345 3.14675 9.0875 3 9.5 3H16.25C16.6625 3 17.0158 3.14675 17.3098 3.44025C17.6033 3.73425 17.75 4.0875 17.75 4.5V13.5C17.75 13.9125 17.6033 14.2658 17.3098 14.5598C17.0158 14.8533 16.6625 15 16.25 15H9.5ZM9.5 13.5H16.25V4.5H9.5V13.5Z"
|
||||
fill="#0276FE"
|
||||
/>
|
||||
</G>
|
||||
|
||||
@@ -10,31 +10,30 @@ import {
|
||||
import { AppDispatch } from '@store';
|
||||
import { PAGE_END } from './constants';
|
||||
|
||||
export const getTopAddresses =
|
||||
(caseId: string, start: number, end: number) => (dispatch: AppDispatch) => {
|
||||
dispatch(setTopAddressesLoading({ caseId, isLoading: true }));
|
||||
const url = getApiUrl(ApiKeys.GET_TOP_ADDRESSES);
|
||||
axiosInstance
|
||||
.get(url, {
|
||||
params: { caseReferenceId: caseId, startingRank: start, endingRank: end },
|
||||
})
|
||||
.then((res) => {
|
||||
if (res?.data) {
|
||||
const { unifiedLocations = [], totalLocationEntities = 0 } = res?.data || {};
|
||||
dispatch(
|
||||
setTopAddresses({
|
||||
caseId,
|
||||
addresses: unifiedLocations,
|
||||
totalLocationEntities: totalLocationEntities - 5,
|
||||
})
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((error) => {})
|
||||
.finally(() => {
|
||||
dispatch(setTopAddressesLoading({ caseId, isLoading: false }));
|
||||
});
|
||||
};
|
||||
export const getTopAddresses = (caseId: string, start: number) => (dispatch: AppDispatch) => {
|
||||
dispatch(setTopAddressesLoading({ caseId, isLoading: true }));
|
||||
const url = getApiUrl(ApiKeys.GET_TOP_ADDRESSES);
|
||||
axiosInstance
|
||||
.get(url, {
|
||||
params: { caseReferenceId: caseId, startingRank: start },
|
||||
})
|
||||
.then((res) => {
|
||||
if (res?.data) {
|
||||
const { unifiedLocations = [], totalLocationEntities = 0 } = res?.data || {};
|
||||
dispatch(
|
||||
setTopAddresses({
|
||||
caseId,
|
||||
addresses: unifiedLocations,
|
||||
totalLocationEntities,
|
||||
})
|
||||
);
|
||||
}
|
||||
})
|
||||
.catch((error) => {})
|
||||
.finally(() => {
|
||||
dispatch(setTopAddressesLoading({ caseId, isLoading: false }));
|
||||
});
|
||||
};
|
||||
|
||||
export const getOtherAddresses = (caseId: string) => (dispatch: AppDispatch) => {
|
||||
dispatch(setOtherAddressesLoading({ caseId, isLoading: true }));
|
||||
|
||||
@@ -1,19 +1,17 @@
|
||||
import { Linking, Pressable, StyleSheet, View } from 'react-native';
|
||||
import { Pressable, StyleSheet, View } from 'react-native';
|
||||
import React from 'react';
|
||||
import Text from '@rn-ui-lib/components/Text';
|
||||
import { ITopAddressItemAddressString, LocationType } from '../interfaces';
|
||||
import LollipopIcon from '@assets/icons/LollipopIcon';
|
||||
import { GenericStyles } from '@rn-ui-lib/styles';
|
||||
import { copyAddressToClipboard } from '@screens/addressGeolocation/utils/copyAddressText';
|
||||
import MapDirectionIcon from '@assets/icons/MapDirectionIcon';
|
||||
import { getGoogleMapUrl } from '@components/utlis/commonFunctions';
|
||||
import CopyOutlineIcon from '@assets/icons/CopyOutlineIcon';
|
||||
import { addClickstreamEvent } from '@services/clickstreamEventService';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
|
||||
|
||||
const AddressItemAddressString = (props: ITopAddressItemAddressString) => {
|
||||
const { locationDetails, showMapIcon = true, caseId, actionContainerStyle } = props;
|
||||
const { addressText, latitude, longitude, locationSubType } = locationDetails || {};
|
||||
const { locationDetails, caseId } = props;
|
||||
const { addressText, locationSubType } = locationDetails || {};
|
||||
|
||||
const handleCopyAddress = () => {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_COPY_ADDRESS_CLICKED, {
|
||||
@@ -27,49 +25,26 @@ const AddressItemAddressString = (props: ITopAddressItemAddressString) => {
|
||||
locationSubType === LocationType.GEO_LOCATION ||
|
||||
locationSubType === LocationType.SKIP_TRACE_ADDRESS;
|
||||
|
||||
const handleOpenLocation = () => {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_OPEN_MAP_BUTTON_CLICKED, {
|
||||
caseId,
|
||||
latitude,
|
||||
longitude,
|
||||
locationSubType,
|
||||
});
|
||||
|
||||
const mapUrl = getGoogleMapUrl(latitude, longitude);
|
||||
|
||||
if (mapUrl) {
|
||||
return Linking.openURL(mapUrl);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={[GenericStyles.mt4, GenericStyles.mr2]}>
|
||||
<LollipopIcon />
|
||||
</View>
|
||||
<View style={styles.fs1}>
|
||||
<Text dark>{addressText}</Text>
|
||||
<View
|
||||
style={[
|
||||
GenericStyles.row,
|
||||
GenericStyles.mt16,
|
||||
GenericStyles.alignCenter,
|
||||
actionContainerStyle,
|
||||
]}
|
||||
>
|
||||
<Pressable onPress={handleCopyAddress} hitSlop={{ top: 8, right: 8, bottom: 8, left: 8 }}>
|
||||
<CopyOutlineIcon />
|
||||
</Pressable>
|
||||
{showMapIcon && isGeoLocation ? (
|
||||
<Pressable
|
||||
onPress={handleOpenLocation}
|
||||
style={GenericStyles.ml20}
|
||||
hitSlop={{ top: 8, right: 8, bottom: 8, left: 8 }}
|
||||
>
|
||||
<MapDirectionIcon />
|
||||
</Pressable>
|
||||
) : null}
|
||||
</View>
|
||||
<Text dark>
|
||||
{addressText}
|
||||
{!isGeoLocation && (
|
||||
<Text>
|
||||
{' '}
|
||||
<Pressable
|
||||
onPress={handleCopyAddress}
|
||||
hitSlop={{ top: 8, right: 8, bottom: 8, left: 8 }}
|
||||
>
|
||||
<CopyOutlineIcon />
|
||||
</Pressable>
|
||||
</Text>
|
||||
)}
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
import { StyleSheet, View } from 'react-native';
|
||||
import { Linking, StyleSheet, View } from 'react-native';
|
||||
import React, { useMemo } from 'react';
|
||||
import { ITopAddressItemHeader } from '../interfaces';
|
||||
import { ITopAddressItemHeader, LocationType } from '../interfaces';
|
||||
import Text from '@rn-ui-lib/components/Text';
|
||||
import { GenericStyles } from '@rn-ui-lib/styles';
|
||||
import { useAppSelector } from '@hooks';
|
||||
import { getDistanceFromLatLonInKm } from '@components/utlis/commonFunctions';
|
||||
import { getDistanceFromLatLonInKm, getGoogleMapUrl } from '@components/utlis/commonFunctions';
|
||||
import relativeDistanceFormatter from '@screens/addressGeolocation/utils/relativeDistanceFormatter';
|
||||
import TopAddressItemRankTag from '../topAddresses/TopAddressItemRankTag';
|
||||
import { COLORS } from '@rn-ui-lib/colors';
|
||||
import { CopilotStep } from '@components/Tour/components/CopilotStep';
|
||||
import Button from '@rn-ui-lib/components/Button';
|
||||
import MapDirectionIcon from '@assets/icons/MapDirectionIcon';
|
||||
import { addClickstreamEvent } from '@services/clickstreamEventService';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
|
||||
|
||||
const AddressItemHeader = (props: ITopAddressItemHeader) => {
|
||||
const { locationDetails, isOtherAddressView, containerStyle, isCoachMarkVisible } = props;
|
||||
const { pinCode, city, latitude, longitude, rank, visited } = locationDetails || {};
|
||||
const { pinCode, city, latitude, longitude, rank, visited, locationSubType } =
|
||||
locationDetails || {};
|
||||
const deviceGeolocationCoordinate = useAppSelector(
|
||||
(state) => state.foregroundService?.deviceGeolocationCoordinate
|
||||
);
|
||||
@@ -25,41 +29,65 @@ const AddressItemHeader = (props: ITopAddressItemHeader) => {
|
||||
return `${relativeDistanceFormatter(distance)} km`;
|
||||
}, [deviceGeolocationCoordinate]);
|
||||
|
||||
const isGeoLocation =
|
||||
locationSubType === LocationType.GEO_LOCATION ||
|
||||
locationSubType === LocationType.SKIP_TRACE_ADDRESS;
|
||||
|
||||
const addressString = useMemo(() => {
|
||||
return [pinCode, city].filter(Boolean).join(', ');
|
||||
}, [pinCode, city]);
|
||||
|
||||
const handleOpenLocation = () => {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_OPEN_MAP_BUTTON_CLICKED, {
|
||||
latitude,
|
||||
longitude,
|
||||
locationSubType,
|
||||
});
|
||||
|
||||
const mapUrl = getGoogleMapUrl(latitude, longitude);
|
||||
|
||||
if (mapUrl) {
|
||||
return Linking.openURL(mapUrl);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={[styles.container, GenericStyles.borderBottom, containerStyle]}>
|
||||
{isOtherAddressView ? (
|
||||
<Text small style={styles.rankCircle}>
|
||||
{rank}
|
||||
</Text>
|
||||
) : isCoachMarkVisible ? (
|
||||
<CopilotStep
|
||||
text="👋 Introducing Ranked Top 5 Addresses!"
|
||||
subText="Visit as per ranks to reach the customer."
|
||||
order={1}
|
||||
name="step 1"
|
||||
>
|
||||
<View>
|
||||
<TopAddressItemRankTag rank={rank} visited={visited} />
|
||||
</View>
|
||||
</CopilotStep>
|
||||
<View style={GenericStyles.row}>
|
||||
<Text small style={styles.rankCircle}>
|
||||
{rank}
|
||||
</Text>
|
||||
<Text
|
||||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
dark
|
||||
style={[GenericStyles.fw700, GenericStyles.pl8, GenericStyles.flex60]}
|
||||
>
|
||||
{addressString ? addressString : '-'}
|
||||
</Text>
|
||||
</View>
|
||||
) : (
|
||||
<TopAddressItemRankTag rank={rank} visited={visited} />
|
||||
)}
|
||||
<View style={[GenericStyles.row, GenericStyles.pr16]}>
|
||||
<Text
|
||||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
dark
|
||||
style={[GenericStyles.fw700, GenericStyles.ml8, styles.mw70]}
|
||||
>
|
||||
{addressString ? addressString : '-'}
|
||||
{!isGeoLocation ? (
|
||||
<Text style={[GenericStyles.fw700, GenericStyles.fontSize12, GenericStyles.pr16]}>
|
||||
{relativeDistanceBwLatLong}
|
||||
</Text>
|
||||
<Text style={GenericStyles.ml8}>({relativeDistanceBwLatLong})</Text>
|
||||
</View>
|
||||
) : (
|
||||
<Button
|
||||
onPress={handleOpenLocation}
|
||||
title={relativeDistanceBwLatLong}
|
||||
variant="primaryText"
|
||||
textStyle={[GenericStyles.fontSize12, GenericStyles.fw500, GenericStyles.mr2]}
|
||||
underlayColor="transparent"
|
||||
rightIcon={<MapDirectionIcon />}
|
||||
pressableWidthChange={false}
|
||||
opacityChangeOnPress={true}
|
||||
style={GenericStyles.pr16}
|
||||
buttonStyle={{ paddingVertical: 0 }}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
@@ -68,6 +96,7 @@ const styles = StyleSheet.create({
|
||||
container: {
|
||||
marginLeft: -5,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
paddingVertical: 8,
|
||||
},
|
||||
|
||||
@@ -45,7 +45,7 @@ const OtherAddressActions = (props: IOtherAddressActions) => {
|
||||
prefilledAddressScreenTemplate,
|
||||
caseId,
|
||||
referenceId,
|
||||
screen: CaseDetailStackEnum.OTHER_ADDRESSES,
|
||||
screen: CaseDetailStackEnum.TOP_ADDRESSES,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
@@ -24,7 +24,7 @@ const TopAddressSimilarAddressCard = (props: ITopAddressSimilarAddressCard) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<View style={[styles.container, GenericStyles.columnDirection, , { flex: 1 }]}>
|
||||
<Pressable style={[styles.container, GenericStyles.columnDirection, , { flex: 1 }]}>
|
||||
<Text dark style={[GenericStyles.fw700]}>
|
||||
{sanitizeString(
|
||||
[similarAddressDetails?.pinCode, similarAddressDetails?.city].filter(Boolean).join(', ')
|
||||
@@ -59,7 +59,7 @@ const TopAddressSimilarAddressCard = (props: ITopAddressSimilarAddressCard) => {
|
||||
) : null}
|
||||
</View>
|
||||
) : null}
|
||||
</View>
|
||||
</Pressable>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
import { ScrollView, StyleSheet, TouchableOpacity, View, useWindowDimensions } from 'react-native';
|
||||
import {
|
||||
Pressable,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
useWindowDimensions,
|
||||
} from 'react-native';
|
||||
import React, { useState } from 'react';
|
||||
import { GenericStyles } from '@rn-ui-lib/styles';
|
||||
import { pluralise } from '@components/utlis/commonFunctions';
|
||||
@@ -63,12 +70,9 @@ const TopAddressSimilarAddresses = (props: ITopAddressSimilarAddresses) => {
|
||||
setVisible={handleClose}
|
||||
>
|
||||
<ScrollView>
|
||||
<AddressItemAddressString
|
||||
locationDetails={locationDetails}
|
||||
showMapIcon={false}
|
||||
actionContainerStyle={GenericStyles.mb16}
|
||||
caseId={caseId}
|
||||
/>
|
||||
<Pressable style={GenericStyles.mb16}>
|
||||
<AddressItemAddressString locationDetails={locationDetails} caseId={caseId} />
|
||||
</Pressable>
|
||||
{similarLocationEntities?.map((entity, index) => (
|
||||
<TopAddressSimilarAddressCard similarAddressDetails={entity} caseId={caseId} />
|
||||
))}
|
||||
|
||||
@@ -1,34 +1,25 @@
|
||||
import { Pressable, StyleSheet, View } from 'react-native';
|
||||
import React, { useEffect } from 'react';
|
||||
import Layout from '@screens/layout/Layout';
|
||||
import { GenericStyles } from '@rn-ui-lib/styles';
|
||||
import NavigationHeader from '@rn-ui-lib/components/NavigationHeader';
|
||||
import { goBack, navigateToScreen } from '@components/utlis/navigationUtlis';
|
||||
import Carousel from '@components/carousel/Carousel';
|
||||
import TopAddressItem from './TopAddressItem';
|
||||
import TopAddressOtherAddressesItem from './TopAddressOtherAddressesItem';
|
||||
import PlusIcon from '@rn-ui-lib/icons/PlusIcon';
|
||||
import { CaseDetailStackEnum } from '@screens/caseDetails/CaseDetailStack';
|
||||
import { COLORS } from '@rn-ui-lib/colors';
|
||||
import Text from '@rn-ui-lib/components/Text';
|
||||
import { getTopAddresses } from '../actions';
|
||||
import { useAppDispatch, useAppSelector } from '@hooks';
|
||||
import LineLoader from '@rn-ui-lib/components/suspense_loader/LineLoader';
|
||||
import { addClickstreamEvent } from '@services/clickstreamEventService';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
|
||||
import { ITopAddress } from '../interfaces';
|
||||
import { PAGE_END, PAGE_START } from '../constants';
|
||||
import { CopilotProvider } from '@components/Tour/contexts/CopilotProvider';
|
||||
import { CopilotStep } from '@components/Tour/components/CopilotStep';
|
||||
import Lottie from '@rn-ui-lib/components/lottie/Lottie';
|
||||
import { PAGE_START } from '../constants';
|
||||
import Layout from '@screens/layout/Layout';
|
||||
import NavigationHeader from '@rn-ui-lib/components/NavigationHeader';
|
||||
import PlusIcon from '@rn-ui-lib/icons/PlusIcon';
|
||||
import TopAddressesList from './TopAddressesList';
|
||||
|
||||
const TopAddresses = ({ route: routeParams }: ITopAddress) => {
|
||||
const {
|
||||
params: { caseId },
|
||||
} = routeParams;
|
||||
const isTopAddressesLoading = useAppSelector(
|
||||
(state) => state.topAddresses?.[caseId]?.isTopAddressesLoading
|
||||
);
|
||||
const addresses = useAppSelector((state) => state.topAddresses?.[caseId]?.addresses || []);
|
||||
const customerReferenceId = useAppSelector(
|
||||
(state) => state.allCases.caseDetails[caseId]?.customerReferenceId
|
||||
@@ -39,9 +30,6 @@ const TopAddresses = ({ route: routeParams }: ITopAddress) => {
|
||||
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
// Added empty object to show "Other Addresses" at the end
|
||||
const updatedAddresses = [...addresses, {}];
|
||||
|
||||
const handleNewAddressCta = () => {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_ADD_NEW_ADDRESS_CLICKED, {
|
||||
caseId,
|
||||
@@ -57,62 +45,28 @@ const TopAddresses = ({ route: routeParams }: ITopAddress) => {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_TOP_ADDRESSES_SCREEN_LOADED, {
|
||||
caseId,
|
||||
});
|
||||
dispatch(getTopAddresses(caseId, PAGE_START, PAGE_END));
|
||||
dispatch(getTopAddresses(caseId, PAGE_START));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<CopilotProvider>
|
||||
<Layout>
|
||||
<View style={[GenericStyles.fill, GenericStyles.blueBackground]}>
|
||||
<NavigationHeader
|
||||
title="Top addresses"
|
||||
onBack={goBack}
|
||||
rightActionable={
|
||||
<CopilotStep text="Tap above to add a new address 👆" order={4} name="step 4">
|
||||
<Pressable
|
||||
onPress={handleNewAddressCta}
|
||||
style={({ pressed }) => [styles.btnContainer, { opacity: pressed ? 0.7 : 1 }]}
|
||||
>
|
||||
<PlusIcon />
|
||||
<Text style={[GenericStyles.whiteText, GenericStyles.lh18]}>New</Text>
|
||||
</Pressable>
|
||||
</CopilotStep>
|
||||
}
|
||||
/>
|
||||
<Carousel
|
||||
data={isTopAddressesLoading ? Array.from({ length: 6 }) : updatedAddresses}
|
||||
isLoading={isTopAddressesLoading}
|
||||
renderItem={({ item, index }) => {
|
||||
if (isTopAddressesLoading) {
|
||||
return (
|
||||
<View>
|
||||
<LineLoader height={'100%'} width={'100%'} style={styles.loader} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
const isLastItem = updatedAddresses?.length - 1 === index;
|
||||
return !isLastItem ? (
|
||||
<TopAddressItem
|
||||
locationDetails={item}
|
||||
caseId={caseId}
|
||||
isCoachMarkVisible={index === 0}
|
||||
/>
|
||||
) : (
|
||||
<TopAddressOtherAddressesItem caseId={caseId} />
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<CopilotStep
|
||||
text="Swipe left to go to next address."
|
||||
order={2}
|
||||
name="step 2"
|
||||
noHighlightArea
|
||||
>
|
||||
<Lottie source={require('@assets/lottie/SwipeAnimation.json')} />
|
||||
</CopilotStep>
|
||||
</View>
|
||||
</Layout>
|
||||
</CopilotProvider>
|
||||
<Layout>
|
||||
<View style={[GenericStyles.fill, GenericStyles.pb24, GenericStyles.silverBackground]}>
|
||||
<NavigationHeader
|
||||
title={`All addresses ${addresses?.length ? `(${addresses?.length})` : ''}`}
|
||||
onBack={goBack}
|
||||
rightActionable={
|
||||
<Pressable
|
||||
onPress={handleNewAddressCta}
|
||||
style={({ pressed }) => [styles.btnContainer, { opacity: pressed ? 0.7 : 1 }]}
|
||||
>
|
||||
<PlusIcon />
|
||||
<Text style={[GenericStyles.whiteText, GenericStyles.lh18]}>New</Text>
|
||||
</Pressable>
|
||||
}
|
||||
/>
|
||||
<TopAddressesList caseId={caseId} />
|
||||
</View>
|
||||
</Layout>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
56
src/screens/addresses/topAddresses/TopAddressesList.tsx
Normal file
56
src/screens/addresses/topAddresses/TopAddressesList.tsx
Normal file
@@ -0,0 +1,56 @@
|
||||
import { ActivityIndicator, FlatList, RefreshControl, StyleSheet, View } from 'react-native';
|
||||
import React from 'react';
|
||||
import { GenericStyles } from '@rn-ui-lib/styles';
|
||||
import { COLORS } from '@rn-ui-lib/colors';
|
||||
import Text from '@rn-ui-lib/components/Text';
|
||||
import { getTopAddresses } from '../actions';
|
||||
import { useAppDispatch, useAppSelector } from '@hooks';
|
||||
import { PAGE_START } from '../constants';
|
||||
import OtherAddressItem from '../otherAddresses/OtherAddressItem';
|
||||
|
||||
const TopAddressesList = ({ caseId }: any) => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const isTopAddressesLoading = useAppSelector(
|
||||
(state) => state.topAddresses?.[caseId]?.isTopAddressesLoading
|
||||
);
|
||||
const addresses = useAppSelector((state) => state.topAddresses?.[caseId]?.addresses || []);
|
||||
|
||||
const onRefresh = React.useCallback(() => {
|
||||
dispatch(getTopAddresses(caseId, PAGE_START));
|
||||
}, []);
|
||||
if (isTopAddressesLoading) {
|
||||
return (
|
||||
<View style={[GenericStyles.fill, GenericStyles.centerAlignedRow]}>
|
||||
<ActivityIndicator size="large" color={COLORS.BASE.BLUE} />
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={GenericStyles.pb16}>
|
||||
{addresses?.length > 0 ? (
|
||||
<FlatList
|
||||
data={addresses}
|
||||
refreshControl={<RefreshControl refreshing={false} onRefresh={onRefresh} />}
|
||||
contentContainerStyle={[GenericStyles.p16, GenericStyles.mb24]}
|
||||
renderItem={({ item }) => <OtherAddressItem locationDetails={item} caseId={caseId} />}
|
||||
/>
|
||||
) : (
|
||||
<View style={[GenericStyles.justifyContentCenter, GenericStyles.alignCenter, styles.h100]}>
|
||||
<Text light style={[GenericStyles.mt16]} dark>
|
||||
No addresses found
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
h100: {
|
||||
height: '100%',
|
||||
},
|
||||
});
|
||||
|
||||
export default TopAddressesList;
|
||||
@@ -1,7 +1,8 @@
|
||||
import MapDirectionFilledIcon from '@assets/icons/MapDirectionFilledIcon';
|
||||
import MapDirectionIcon from '@assets/icons/MapDirectionIcon';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
|
||||
import {
|
||||
getDistanceFromLatLonInKm,
|
||||
getGoogleMapUrl,
|
||||
getGoogleMapUrlForAddressText,
|
||||
} from '@components/utlis/commonFunctions';
|
||||
import { useAppSelector } from '@hooks';
|
||||
@@ -11,6 +12,7 @@ import Button from '@rn-ui-lib/components/Button';
|
||||
import Text from '@rn-ui-lib/components/Text';
|
||||
import { toast } from '@rn-ui-lib/components/toast';
|
||||
import { GenericStyles } from '@rn-ui-lib/styles';
|
||||
import { AddressTabType } from '@screens/addressGeolocation/constant';
|
||||
import relativeDistanceFormatter from '@screens/addressGeolocation/utils/relativeDistanceFormatter';
|
||||
import { addClickstreamEvent } from '@services/clickstreamEventService';
|
||||
import React, { useMemo } from 'react';
|
||||
@@ -21,10 +23,11 @@ interface IAllocatedAddressDetails {
|
||||
addressLocation: IGeolocationCoordinate;
|
||||
caseId: string;
|
||||
addressString?: string;
|
||||
addressStringType?: string;
|
||||
}
|
||||
|
||||
const AllocatedAddressDetails = (props: IAllocatedAddressDetails) => {
|
||||
const { isCasePaused, addressLocation, addressString, caseId } = props;
|
||||
const { isCasePaused, addressLocation, addressString, caseId, addressStringType } = props;
|
||||
const deviceGeolocationCoordinate = useAppSelector(
|
||||
(state) => state.foregroundService?.deviceGeolocationCoordinate
|
||||
);
|
||||
@@ -37,15 +40,20 @@ const AllocatedAddressDetails = (props: IAllocatedAddressDetails) => {
|
||||
return `${relativeDistanceFormatter(distance)} km`;
|
||||
}, [deviceGeolocationCoordinate]);
|
||||
|
||||
const isGeolocation = addressStringType === AddressTabType.GEO_LOCATION;
|
||||
|
||||
const openLocation = () => {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_DIRECTIONS_BUTTON_CLICKED, {
|
||||
caseId,
|
||||
});
|
||||
if (!addressString) {
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_DIRECTIONS_BUTTON_CLICKED, { caseId });
|
||||
let mapUrl: string | undefined;
|
||||
if (isGeolocation) {
|
||||
mapUrl = getGoogleMapUrl(addressLocation?.latitude, addressLocation?.longitude);
|
||||
} else if (addressString) {
|
||||
mapUrl = getGoogleMapUrlForAddressText(addressString);
|
||||
} else {
|
||||
toast({ type: 'error', text1: 'Address not available' });
|
||||
return;
|
||||
}
|
||||
const mapUrl = getGoogleMapUrlForAddressText(addressString);
|
||||
|
||||
if (!mapUrl) return;
|
||||
return Linking.openURL(mapUrl);
|
||||
};
|
||||
@@ -57,39 +65,30 @@ const AllocatedAddressDetails = (props: IAllocatedAddressDetails) => {
|
||||
GenericStyles.justifyContentSpaceBetween,
|
||||
]}
|
||||
>
|
||||
<View style={GenericStyles.centerAlignedRow}>
|
||||
<Text style={styles.details}>Allocated Address</Text>
|
||||
<View style={styles.bullet} />
|
||||
<Text style={styles.details}>{relativeDistanceBwLatLong}</Text>
|
||||
</View>
|
||||
<Button
|
||||
onPress={openLocation}
|
||||
title="Directions"
|
||||
variant="primaryText"
|
||||
buttonStyle={styles.pv0}
|
||||
textStyle={[GenericStyles.fontSize13, GenericStyles.fw500]}
|
||||
leftIcon={
|
||||
<View style={GenericStyles.mr4}>
|
||||
<MapDirectionFilledIcon />
|
||||
</View>
|
||||
}
|
||||
underlayColor="transparent"
|
||||
pressableWidthChange={false}
|
||||
opacityChangeOnPress={true}
|
||||
disabled={isCasePaused}
|
||||
/>
|
||||
<Text style={styles.details}>Allocated Address</Text>
|
||||
{!isGeolocation ? (
|
||||
<Text style={[GenericStyles.fw700, GenericStyles.fontSize12, GenericStyles.pr16]}>
|
||||
{relativeDistanceBwLatLong}
|
||||
</Text>
|
||||
) : (
|
||||
<Button
|
||||
onPress={openLocation}
|
||||
title={relativeDistanceBwLatLong}
|
||||
variant="primaryText"
|
||||
textStyle={[GenericStyles.fontSize12, GenericStyles.fw500, GenericStyles.mr2]}
|
||||
underlayColor="transparent"
|
||||
rightIcon={<MapDirectionIcon />}
|
||||
pressableWidthChange={false}
|
||||
opacityChangeOnPress={true}
|
||||
buttonStyle={styles.pv0}
|
||||
disabled={isCasePaused}
|
||||
/>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
export const styles = StyleSheet.create({
|
||||
bullet: {
|
||||
width: 5,
|
||||
height: 5,
|
||||
borderRadius: 4,
|
||||
backgroundColor: COLORS.TEXT.GREY_5,
|
||||
marginHorizontal: 6,
|
||||
},
|
||||
details: {
|
||||
fontSize: 13,
|
||||
color: COLORS.TEXT.GREY_5,
|
||||
|
||||
@@ -76,6 +76,7 @@ const ViewAddressSection = ({ caseId }: IViewAddressSection) => {
|
||||
isCasePaused={isCasePaused}
|
||||
addressLocation={addressLocation}
|
||||
addressString={addressString}
|
||||
addressStringType={addressStringType}
|
||||
caseId={caseId}
|
||||
/>
|
||||
<View style={styles.container}>
|
||||
@@ -88,7 +89,7 @@ const ViewAddressSection = ({ caseId }: IViewAddressSection) => {
|
||||
</Text>
|
||||
<Button
|
||||
onPress={viewTopAddressHandler}
|
||||
title="View top addresses"
|
||||
title="View all addresses"
|
||||
variant="primaryText"
|
||||
textStyle={[GenericStyles.fontSize13, GenericStyles.fw500]}
|
||||
style={styles.mb5}
|
||||
|
||||
Reference in New Issue
Block a user