diff --git a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java index 56c69465..f05a1756 100644 --- a/android/app/src/main/java/com/avapp/DeviceUtilsModule.java +++ b/android/app/src/main/java/com/avapp/DeviceUtilsModule.java @@ -21,6 +21,9 @@ import org.json.JSONObject; import java.util.List; +import android.net.Uri; +import android.util.Log; + public class DeviceUtilsModule extends ReactContextBaseJavaModule implements ActivityEventListener { private ReactApplicationContext RNContext; @@ -77,4 +80,40 @@ public class DeviceUtilsModule extends ReactContextBaseJavaModule implements Act promise.reject( err); } } + + // @ReactMethod + // public void sendFeedbackToWhatsapp(String encodedMessage, String encodedImageUri, String mimeType) { + // log.d("Native Function is called"); + // log.d("sendFeedbackToWhatsapp", encodedMessage, encodedImageUri, mimeType); + // Intent sendIntent = new Intent(); + // sendIntent.setAction(Intent.ACTION_SEND); + // sendIntent.putExtra(Intent.EXTRA_TEXT, encodedMessage); + // sendIntent.setType(mimeType); + // sendIntent.putExtra(Intent.EXTRA_STREAM, encodedImageUri); + + // sendIntent.setPackage("com.whatsapp"); + // startActivity(sendIntent); + // return; + // } + + @ReactMethod + public void sendFeedbackToWhatsapp(String encodedMessage, String encodedImageUri, String mimeType) { + Log.d("Native Function called","string eg"); + + Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_TEXT, encodedMessage); + sendIntent.setType(mimeType); + + // Convert the encodedImageUri to a URI and set it as an EXTRA_STREAM + Uri uri = Uri.parse(encodedImageUri); + sendIntent.putExtra(Intent.EXTRA_STREAM, uri); + + sendIntent.setPackage("com.whatsapp"); + + // Start the activity + getCurrentActivity().startActivity(sendIntent); + return; + } + } diff --git a/package.json b/package.json index daf8f1ef..93284aee 100644 --- a/package.json +++ b/package.json @@ -72,6 +72,7 @@ "react-native-qrcode-svg": "^6.2.0", "react-native-safe-area-context": "4.4.1", "react-native-screens": "3.18.2", + "react-native-send-intent": "^1.3.0", "react-native-share": "^9.4.1", "react-native-svg": "^13.9.0", "react-native-tab-view": "3.3.2", diff --git a/src/assets/icons/ChevronDown.tsx b/src/assets/icons/ChevronDown.tsx index d9f0db95..06080164 100644 --- a/src/assets/icons/ChevronDown.tsx +++ b/src/assets/icons/ChevronDown.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; import Svg, { Rect, Mask, Path, G } from 'react-native-svg'; - const ChevronDown = (props) => ( diff --git a/src/constants/icons/ExpandAccordian.ts b/src/constants/icons/ExpandAccordian.ts new file mode 100644 index 00000000..388254fd --- /dev/null +++ b/src/constants/icons/ExpandAccordian.ts @@ -0,0 +1,2 @@ +export const expandAccordianPath = + 'M8.466 1.233a.63.63 0 0 0-.183.465.63.63 0 0 0 .183.465l3.057 3.055a.587.587 0 0 0 .216.141.742.742 0 0 0 .25.041c.088 0 .171-.013.249-.04.077-.029.15-.076.216-.142l3.073-3.072a.609.609 0 0 0 .183-.448.637.637 0 0 0-.2-.465.63.63 0 0 0-.465-.183.63.63 0 0 0-.465.183l-2.592 2.59-2.608-2.607a.61.61 0 0 0-.449-.182.638.638 0 0 0-.465.199Z'; diff --git a/src/constants/icons/ShrinkAccordian.ts b/src/constants/icons/ShrinkAccordian.ts new file mode 100644 index 00000000..cbd78f0f --- /dev/null +++ b/src/constants/icons/ShrinkAccordian.ts @@ -0,0 +1,2 @@ +export const shrinkAccordianPath = + 'M8.466 13.767a.63.63 0 0 1-.183-.465.63.63 0 0 1 .183-.465l3.057-3.055a.587.587 0 0 1 .216-.141.742.742 0 0 1 .25-.041c.088 0 .171.013.249.04.077.029.15.076.216.142l3.073 3.072a.609.609 0 0 1 .183.448.637.637 0 0 1-.2.465.63.63 0 0 1-.465.183.63.63 0 0 1-.465-.183l-2.592-2.59-2.608 2.607a.61.61 0 0 1-.449.182.638.638 0 0 1-.465-.199Z'; diff --git a/src/screens/caseDetails/CollectionCaseDetail.tsx b/src/screens/caseDetails/CollectionCaseDetail.tsx index fbeb55c8..bdba53f3 100644 --- a/src/screens/caseDetails/CollectionCaseDetail.tsx +++ b/src/screens/caseDetails/CollectionCaseDetail.tsx @@ -206,8 +206,9 @@ const CollectionCaseDetails: React.FC = (props) => { const commonParams = { loanAccountNumber: caseDetail.loanAccountNumber, customerReferenceId: caseDetail.customerReferenceId, - caseId, + caseId: caseId, }; + console.log(caseId); navigateToScreen(route, { ...params, ...commonParams }); }; @@ -454,6 +455,7 @@ const CollectionCaseDetails: React.FC = (props) => { diff --git a/src/screens/caseDetails/feedback/FeedbackDetailContainer.tsx b/src/screens/caseDetails/feedback/FeedbackDetailContainer.tsx index 3a19a0db..9ed3ce77 100644 --- a/src/screens/caseDetails/feedback/FeedbackDetailContainer.tsx +++ b/src/screens/caseDetails/feedback/FeedbackDetailContainer.tsx @@ -4,6 +4,7 @@ import Accordion from '../../../../RN-UI-LIB/src/components/accordian/Accordian' 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 Chevron from '../../../../RN-UI-LIB/src/Icons/Chevron'; import { COLORS } from '../../../../RN-UI-LIB/src/styles/colors'; import { getPastFeedbacks, getPastFeedbacksOnAddresses } from '../../../action/feedbackActions'; import { GenericType } from '../../../common/GenericTypes'; @@ -25,6 +26,8 @@ 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 { expandAccordianPath } from '../../../constants/icons/ExpandAccordian'; +import { shrinkAccordianPath } from '../../../constants/icons/ShrinkAccordian'; const FEEDBACK_PAGE_TITLE = 'All feedbacks'; const ADDRESS_FEEDBACK_PAGE_TITLE = 'Address feedback'; @@ -32,6 +35,22 @@ const ADDRESS_FEEDBACK_PAGE_TITLE = 'Address feedback'; const SCROLL_LAYOUT_OFFSET = 10; const FEEDBACK_PER_PAGE = 5; +const shrinkAccordianProps = { + width: 24, + height: 24, + fillColor: '#0276FE', + rotateY: 0, + path: shrinkAccordianPath, +}; + +const expandAccordianProps = { + width: 24, + height: 24, + fillColor: '#0276FE', + rotateY: 0, + path: expandAccordianPath, +}; + interface IFeedbackDetailContainer { route: { params: { @@ -39,15 +58,24 @@ interface IFeedbackDetailContainer { addressReferenceIds?: string[]; addressText?: string; activeFeedbackReferenceId?: string; + caseID: string; }; }; } const FeedbackDetailContainer: React.FC = ({ route: routeParams }) => { const { - params: { loanAccountNumber, activeFeedbackReferenceId, addressReferenceIds, addressText }, + params: { + loanAccountNumber, + activeFeedbackReferenceId, + addressReferenceIds, + addressText, + caseID, + }, } = routeParams; + console.log({ routeParams }); + const isPastFeedbackOnAddress = addressText || addressReferenceIds?.length; const [isExpanded, setIsExpanded] = useState(false); @@ -221,11 +249,12 @@ const FeedbackDetailContainer: React.FC = ({ route: ro key={feedback.referenceId} feedbackItem={feedback} isExpanded={isExpanded} + caseID={caseID} /> } customExpandUi={{ - whenCollapsed: View more, - whenExpanded: View less, + whenCollapsed: , + whenExpanded: , }} onExpanded={(value) => { setIsExpanded(value); diff --git a/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx b/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx index 44439a18..d58960bf 100644 --- a/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx +++ b/src/screens/caseDetails/feedback/FeedbackDetailItem.tsx @@ -1,5 +1,5 @@ import React, { ReactNode } from 'react'; -import { View, StyleSheet, TouchableOpacity, Linking } from 'react-native'; +import { View, StyleSheet, TouchableOpacity, Linking, Platform, NativeModules } 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'; @@ -25,17 +25,21 @@ import IconLabel from '../../../common/IconLabel'; import WhatsAppFeedbackShareIcon from '../../../assets/icons/WhatsAppIcon'; import RNFetchBlob from 'rn-fetch-blob'; import Share from 'react-native-share'; +import { useAppSelector } from '../../../hooks'; +import { InteractionStatuses } from '../../allCases/interface'; +const { DeviceUtilsModule } = NativeModules; interface IFeedbackDetailItem { feedbackItem: IFeedback; isExpanded: boolean; + caseID: string; } const feedbackTypeIcon: Record = { - FIELD_VISIT: , - INHOUSE_FIELD_VISIT: , - SELF_CALL: , - CALL_BRIDGE: , + FIELD_VISIT: , + INHOUSE_FIELD_VISIT: , + SELF_CALL: , + CALL_BRIDGE: , }; const getAddress = (address?: IAddress) => { @@ -61,14 +65,26 @@ function getLocationLink(latitude: string, longitude: string): string { return link; } -const sendToWhatsapp = (feedbackItem: IFeedback) => { - var message = ''; - message += 'Feedback Type: ' + sanitizeString(feedbackItem.type) + '\n\n'; - message += 'Disposition: ' + sanitizeString(feedbackItem.interactionStatus) + '\n\n'; +const sendToWhatsapp = (feedbackItem: IFeedback, caseDetails: any) => { + var message = '*Visit Feedback for* ' + sanitizeString(caseDetails?.customerName) + '\n'; message += - 'Feedback Date and Time: ' + - sanitizeString(dateFormat(new Date(feedbackItem.createdAt), 'DD MMM YYYY, HH:mm A')) + - '\n\n'; + sanitizeString(dateFormat(new Date(feedbackItem.createdAt), 'DD MMM YYYY | HH:mm A')) + '\n\n'; + message += 'LAN: ' + sanitizeString(caseDetails?.loanAccountNumber); + message += '| DPD Bucket: ' + sanitizeString(caseDetails?.dpdBucket) + '\n\n'; + message += 'Disposition: ' + sanitizeString(feedbackItem.interactionStatus); + console.log('PRIIIIIIIINTINGGGGGGGGGGGGGGGG'); + console.log(feedbackItem); + const ptpDate = feedbackItem.answerViews.filter((answer) => answer.questionName === 'PTP Date'); + if (ptpDate.length > 0) { + message += ' for ' + sanitizeString(ptpDate[0].inputDate) + '\n\n'; + } + const answerList = feedbackItem.answerViews.filter( + (answer) => answer.questionName === 'Comments' + ); + if (answerList.length > 0) { + message += 'Comments: ' + sanitizeString(answerList[0].inputText) + '\n\n'; + } + { feedbackItem.metadata?.interactionLatitude && feedbackItem.metadata?.interactionLongitude && @@ -116,6 +132,7 @@ const sendToWhatsapp = (feedbackItem: IFeedback) => { console.log(imageUrl); console.log(url); //Linking.openURL(url); + ////////////////////////////////////////////////////////////// let shareImage = { title: 'Agent Feedback', message: message, @@ -123,9 +140,9 @@ const sendToWhatsapp = (feedbackItem: IFeedback) => { social: Share.Social.WHATSAPP, }; //console.log(shareImage); - Share.open(shareImage); - return RNFetchBlob.fs.unlink(imagePath); - + //Share.open(shareImage); + //return RNFetchBlob.fs.unlink(imagePath); + //////////////////////////////////////////////////////////////// // Linking.canOpenURL(url) // .then(isInstalled => { // if (!isInstalled) { @@ -138,80 +155,112 @@ const sendToWhatsapp = (feedbackItem: IFeedback) => { // } // }) // .catch(error => console.error('An error occurred', error)); + + // const sendIntent = Platform.select({ + // ios: null, + // android: { + // action: 'android.intent.action.SEND', + // intentType: 'text/plain', + // extras: { + // 'android.intent.extra.TEXT': encodedMessage, + // 'android.intent.extra.STREAM': encodedImageUri, + // 'android.intent.extra.SUBJECT': 'Subject', + // }, + // packageName: 'com.whatsapp', + // }, + // }); + + // return Linking.openURL(sendIntent); + const mimeType = 'image/*'; + console.log(DeviceUtilsModule); + DeviceUtilsModule.sendFeedbackToWhatsApp(message, imageUri, mimeType); }); }; -const FeedbackDetailItem = ({ feedbackItem, isExpanded }: IFeedbackDetailItem) => { +const FeedbackDetailItem = ({ feedbackItem, isExpanded, caseID }: IFeedbackDetailItem) => { + const caseDetails = useAppSelector((state) => state.allCases.caseDetails[caseID]); return ( - - - {feedbackTypeIcon[feedbackItem.type] ? ( - {feedbackTypeIcon[feedbackItem.type]} - ) : null} + console.log(caseID), + console.log(caseDetails), + ( + + + {feedbackTypeIcon[feedbackItem.type] ? ( + {feedbackTypeIcon[feedbackItem.type]} + ) : null} + + {sanitizeString(feedbackItem.interactionStatus)} + + - {sanitizeString(feedbackItem.interactionStatus)} + {sanitizeString(dateFormat(new Date(feedbackItem.createdAt), BUSINESS_DATE_FORMAT))} +   ●   + {sanitizeString(dateFormat(new Date(feedbackItem.createdAt), BUSINESS_TIME_FORMAT))} + + + {FIELD_FEEDBACKS.includes(feedbackItem.type) + ? sanitizeString(getAddress(feedbackItem.source as IAddress)) + : sanitizeString( + [ + (feedbackItem.source as ICallingFeedback)?.recipientNumber, + feedbackItem.sourceText ? `(${feedbackItem.sourceText})` : '', + ].join(' ') + )} - - - {sanitizeString(dateFormat(new Date(feedbackItem.createdAt), BUSINESS_DATE_FORMAT))} -   ●   - {sanitizeString(dateFormat(new Date(feedbackItem.createdAt), BUSINESS_TIME_FORMAT))} - - - - {FIELD_FEEDBACKS.includes(feedbackItem.type) - ? sanitizeString(getAddress(feedbackItem.source as IAddress)) - : sanitizeString( - [ - (feedbackItem.source as ICallingFeedback)?.recipientNumber, - feedbackItem.sourceText ? `(${feedbackItem.sourceText})` : '', - ].join(' ') - )} - - {feedbackItem.metadata?.interactionLatitude && FIELD_FEEDBACKS.includes(feedbackItem.type) ? ( - <> - - - openGeolocation( - feedbackItem.metadata?.interactionLatitude, - feedbackItem.metadata?.interactionLongitude - ) - } - style={[GenericStyles.row, GenericStyles.pv12]} - > - Open map - - sendToWhatsapp(feedbackItem)}> - } - textStyle={{ color: COLORS.BASE.BLUE }} - /> - - - - ) : null} - + {feedbackItem.metadata?.interactionLatitude && + FIELD_FEEDBACKS.includes(feedbackItem.type) ? ( + <> + + + openGeolocation( + feedbackItem.metadata?.interactionLatitude, + feedbackItem.metadata?.interactionLongitude + ) + } + style={[GenericStyles.row, GenericStyles.pv12]} + > + Open map + + sendToWhatsapp(feedbackItem, caseDetails)} + > + } + textStyle={{ color: COLORS.BASE.BLUE }} + /> + + + + ) : null} + + ) ); }; diff --git a/src/screens/caseDetails/feedback/FeedbackListContainer.tsx b/src/screens/caseDetails/feedback/FeedbackListContainer.tsx index 721f983b..485087e8 100644 --- a/src/screens/caseDetails/feedback/FeedbackListContainer.tsx +++ b/src/screens/caseDetails/feedback/FeedbackListContainer.tsx @@ -18,6 +18,7 @@ import { getCaseUnifiedData, UnifiedCaseDetailsTypes } from '../../../action/cas interface IFeedbackListContainer { loanAccountNumber: string; feedbackList: (IFeedback | IUnSyncedFeedbackItem)[]; + caseID: string; } interface IOfflineFeedbackListContainer { @@ -66,6 +67,7 @@ const OfflineFeedbackListContainer: React.FC = ({ const FeedbackListContainer: React.FC = ({ loanAccountNumber, feedbackList, + caseID, }) => { const [retryBtnCount, setRetryBtnCount] = useState(0); @@ -91,15 +93,19 @@ const FeedbackListContainer: React.FC = ({ } return ( - - {feedbackList.map((feedbackItem: IFeedback | IUnSyncedFeedbackItem, idx: number) => ( - - ))} - + console.log(caseID), + ( + + {feedbackList.map((feedbackItem: IFeedback | IUnSyncedFeedbackItem, idx: number) => ( + + ))} + + ) ); }; diff --git a/src/screens/caseDetails/feedback/FeedbackListItem.tsx b/src/screens/caseDetails/feedback/FeedbackListItem.tsx index 3b7c06a7..8a8a3184 100644 --- a/src/screens/caseDetails/feedback/FeedbackListItem.tsx +++ b/src/screens/caseDetails/feedback/FeedbackListItem.tsx @@ -15,11 +15,13 @@ interface IFeedbackListItem { feedbackItem: IFeedback | IUnSyncedFeedbackItem; showHorizontalLine?: boolean; loanAccountNumber: string; + caseID: string; } const FeedbackListItem: React.FC = ({ feedbackItem, loanAccountNumber, + caseID, showHorizontalLine = true, }) => { const handleRouting = (route: PageRouteEnum, params: object | undefined = undefined) => { @@ -27,7 +29,9 @@ const FeedbackListItem: React.FC = ({ const commonParams = { loanAccountNumber, activeFeedbackReferenceId: (feedbackItem as IFeedback).referenceId, + caseID: caseID, }; + console.log(caseID); navigateToScreen(route, { ...params, ...commonParams }); }; diff --git a/yarn.lock b/yarn.lock index 138c81b8..305e30da 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7820,6 +7820,11 @@ react-native-screens@3.18.2: react-freeze "^1.0.0" warn-once "^0.1.0" +react-native-send-intent@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/react-native-send-intent/-/react-native-send-intent-1.3.0.tgz#d8c7898827da1b8b10e25a645ce6802d1a0b440c" + integrity sha512-ODTX7BHITFxdcAL0K2iHfa3qVYnqG8GPcv1NbLBNC1DyCaOSJiiGtVH6Kc5YBqzQ8+1pV9uN5nfQ5wyFgiq74g== + react-native-share@^9.4.1: version "9.4.1" resolved "https://registry.yarnpkg.com/react-native-share/-/react-native-share-9.4.1.tgz#1b6d96015009e3878bfc4346940602c1cffff525"