176 lines
5.6 KiB
TypeScript
176 lines
5.6 KiB
TypeScript
import React, { useEffect, useRef } from 'react';
|
|
import { StyleSheet, View, TouchableOpacity, Pressable } from 'react-native';
|
|
import Animated, { SharedValue, useAnimatedStyle } from 'react-native-reanimated';
|
|
import { COLORS } from '@rn-ui-lib/colors';
|
|
import { useAppSelector } from '@hooks';
|
|
import RightChevronIcon from '@assets/icons/RightChevronIcon';
|
|
import FeedbackStatus from '@screens/allCases/CaseItem/FeedbackStatus';
|
|
import ProfileHeader from '../ProfileHeader';
|
|
import { AddressTabType } from '@screens/addressGeolocation/constant';
|
|
import { navigateToScreen } from '@components/utlis/navigationUtlis';
|
|
import { PageRouteEnum } from '@screens/auth/ProtectedRouter';
|
|
import { CaseDetailStackEnum } from '@screens/caseDetails/CaseDetailStack';
|
|
import { GenericStyles } from '@rn-ui-lib/styles';
|
|
import { CASE_CARD_Z_INDEX } from '../constants';
|
|
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
|
|
import { addClickstreamEvent } from '@services/clickstreamEventService';
|
|
import CopyOutlineIcon from '@assets/icons/CopyOutlineIcon';
|
|
import { copyAddressToClipboard } from '@screens/addressGeolocation/utils/copyAddressText';
|
|
import Text from '@rn-ui-lib/components/Text';
|
|
|
|
interface UserCardProps {
|
|
selectedCase: string;
|
|
cardPosition: SharedValue<number>;
|
|
}
|
|
|
|
const UserCard: React.FC<UserCardProps> = ({ selectedCase, cardPosition }) => {
|
|
const caseDetail = useAppSelector((state) => state.allCases?.caseDetails?.[selectedCase]) || {};
|
|
const addressItemRef = useRef(null);
|
|
|
|
const cardAnimatedStyle = useAnimatedStyle(() => {
|
|
const positionValue = Number.isNaN(cardPosition.value) ? 1 : cardPosition.value;
|
|
return {
|
|
transform: [
|
|
{
|
|
translateY: (1 - positionValue) * 220, // 220 is the height of the card here as the profile picture takes the extra space
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
const onTopAddressesPress = () => {
|
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_MAP_CASE_CARD_TOP_ADDRESSES_CLICKED, {
|
|
markerId: selectedCase,
|
|
});
|
|
navigateToScreen(PageRouteEnum.CASE_DETAIL_STACK, {
|
|
screen: CaseDetailStackEnum.MAP_VIEW_TOP_ADDRESS,
|
|
params: { caseId: selectedCase },
|
|
});
|
|
};
|
|
|
|
const handleCardPress = () => {
|
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_MAP_CASE_CARD_CLICKED, {
|
|
markerId: selectedCase,
|
|
});
|
|
navigateToScreen(PageRouteEnum.CASE_DETAIL_STACK, {
|
|
screen: CaseDetailStackEnum.COLLECTION_CASE_DETAIL,
|
|
params: { caseId: selectedCase },
|
|
});
|
|
};
|
|
|
|
const handleCopyAddress = () => {
|
|
if (!caseDetail?.addressString) return;
|
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_MAP_COPY_ADDRESS_CLICKED, {
|
|
caseId: selectedCase,
|
|
addressText: caseDetail?.addressString,
|
|
});
|
|
copyAddressToClipboard(caseDetail?.addressString);
|
|
};
|
|
|
|
const isGeolocation = caseDetail?.addressStringType === AddressTabType.GEO_LOCATION;
|
|
|
|
useEffect(() => {
|
|
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_MAP_CASE_CARD_LOADED, {
|
|
markerId: selectedCase,
|
|
});
|
|
}, []);
|
|
|
|
return (
|
|
<Animated.View style={[styles.cardContainer, cardAnimatedStyle]}>
|
|
<Pressable
|
|
style={({ pressed }) => [pressed && { opacity: 0.9 }]}
|
|
ref={addressItemRef}
|
|
onPress={handleCardPress}
|
|
>
|
|
<ProfileHeader
|
|
caseId={selectedCase}
|
|
showDirections={true}
|
|
addressItemRef={addressItemRef}
|
|
/>
|
|
<View style={styles.dashedBorder} />
|
|
<View style={styles.cardContent}>
|
|
<View style={styles.h66}>
|
|
<View style={styles.addressContainer}>
|
|
<Text numberOfLines={2} ellipsizeMode="tail" style={styles.addressText}>
|
|
{!isGeolocation && (
|
|
<Text dark style={[GenericStyles.lh18, GenericStyles.fontSize12]}>
|
|
{caseDetail?.currentPinCode}
|
|
{' - '}
|
|
</Text>
|
|
)}
|
|
|
|
{caseDetail?.addressString}
|
|
</Text>
|
|
{!isGeolocation && (
|
|
<Pressable
|
|
onPress={handleCopyAddress}
|
|
hitSlop={{ top: 12, right: 12, bottom: 12, left: 12 }}
|
|
>
|
|
<CopyOutlineIcon />
|
|
</Pressable>
|
|
)}
|
|
</View>
|
|
<TouchableOpacity
|
|
activeOpacity={0.8}
|
|
style={[GenericStyles.row, GenericStyles.alignSelfStart]}
|
|
hitSlop={{ top: 8, right: 8, bottom: 8, left: 8 }}
|
|
onPress={onTopAddressesPress}
|
|
>
|
|
<Text style={styles.topaddressesButtonText}>All addresses</Text>
|
|
<RightChevronIcon />
|
|
</TouchableOpacity>
|
|
</View>
|
|
<FeedbackStatus caseListItemDetailObj={caseDetail} isMapView={true} />
|
|
</View>
|
|
</Pressable>
|
|
</Animated.View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
addressContainer: {
|
|
alignItems: 'flex-start',
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
marginBottom: 4,
|
|
},
|
|
h66: {
|
|
height: 66,
|
|
},
|
|
addressText: {
|
|
color: COLORS.TEXT.LIGHT,
|
|
flex: 1,
|
|
fontSize: 12,
|
|
lineHeight: 18,
|
|
},
|
|
cardContainer: {
|
|
backgroundColor: COLORS.BACKGROUND.PRIMARY,
|
|
bottom: 0,
|
|
left: 0,
|
|
paddingBottom: 16,
|
|
paddingTop: 16,
|
|
position: 'absolute',
|
|
right: 0,
|
|
zIndex: CASE_CARD_Z_INDEX,
|
|
},
|
|
cardContent: {
|
|
flex: 1,
|
|
paddingHorizontal: 16,
|
|
},
|
|
dashedBorder: {
|
|
borderColor: COLORS.BORDER.PRIMARY,
|
|
borderStyle: 'dashed',
|
|
borderTopWidth: 1,
|
|
marginBottom: 8,
|
|
marginTop: 4,
|
|
},
|
|
topaddressesButtonText: {
|
|
color: COLORS.TEXT.BLUE,
|
|
fontSize: 12,
|
|
fontWeight: '500',
|
|
lineHeight: 18,
|
|
},
|
|
});
|
|
|
|
export default UserCard;
|