From 0bea52130d58c5d9bebe781bab5e3104e5ae348e Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Thu, 21 Nov 2024 13:04:36 -0500 Subject: [PATCH 01/16] feature/Binny-10233-CreatePIIFilter --- VAMobile/src/constants/common.ts | 3 + .../InAppFeedbackScreen.tsx | 25 +++++++- VAMobile/src/utils/common.ts | 58 +++++++++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/VAMobile/src/constants/common.ts b/VAMobile/src/constants/common.ts index 44a1ff0df2b..31a71876e17 100644 --- a/VAMobile/src/constants/common.ts +++ b/VAMobile/src/constants/common.ts @@ -57,6 +57,9 @@ export const MAIL_TO_REGEX_EXP = new RegExp( export const PHONE_REGEX_EXP = new RegExp( /^\s*(?:\+?(\d{0,3}))?[-. (]*(\d{3})[-. )]*(\d{3})[-. ]*(\d{4})(?: *(x)(\d+))?,?.?\s*$/, ) + +export const SSN_REGEX_EXP = new RegExp(/^\d{3}-?\d{2}-?\d{4}$/) + export const NUMBERS_ONLY_REGEX_EXP = new RegExp(/^[0-9]/) export const URL_REGEX_EXP = new RegExp(/^((https:|http:)\S*)/) diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx index 460de551d53..a030113d1c9 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx @@ -1,6 +1,6 @@ import React, { useState } from 'react' import { useTranslation } from 'react-i18next' -import { Pressable } from 'react-native' +import { Alert, Pressable } from 'react-native' import { StackScreenProps } from '@react-navigation/stack/lib/typescript/src/types' @@ -9,6 +9,7 @@ import { RootNavStackParamList } from 'App' import { BorderColorVariant, Box, LargePanel, RadioGroup, RadioGroupProps, TextView, VATextInput } from 'components' import { NAMESPACE } from 'constants/namespaces' +import { checkStringForPII } from 'utils/common' import getEnv from 'utils/env' import { useExternalLink, useTheme } from 'utils/hooks' @@ -28,8 +29,28 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { // }) const onSubmit = (): void => { + const { found, newText } = checkStringForPII(task) // logAnalyticsEvent(Events.vama_feedback_submitted(taskCompleted, satisfaction)) - navigation.goBack() + if (found) { + console.log('Before task: ', task) + Alert.alert('Please Remove PII', 'We detected something that seems like PII, please remove it to continue', [ + { + text: 'Return to feedback', + style: 'cancel', + onPress: () => {}, + }, + { + text: 'submit anyways', + onPress: () => { + setTaskOverride(newText) + console.log('After task: ', task) + navigation.goBack() + }, + }, + ]) + } else { + navigation.goBack() + } } const radioGroupProps: RadioGroupProps = { diff --git a/VAMobile/src/utils/common.ts b/VAMobile/src/utils/common.ts index 27d7edaddb4..4ded47a242c 100644 --- a/VAMobile/src/utils/common.ts +++ b/VAMobile/src/utils/common.ts @@ -8,12 +8,14 @@ import { StackCardInterpolatedStyle, StackCardInterpolationProps } from '@react- import { TFunction } from 'i18next' import { DateTime } from 'luxon' import { contains, isEmpty, map } from 'underscore' +import _ from 'underscore' import { PhoneData } from 'api/types/PhoneData' import { TextLineWithIconProps } from 'components' import { InlineTextWithIconsProps } from 'components/InlineTextWithIcons' import { TextLine } from 'components/types' import { Events } from 'constants/analytics' +import { EMAIL_REGEX_EXP, MAIL_TO_REGEX_EXP, PHONE_REGEX_EXP, SSN_REGEX_EXP } from 'constants/common' import { DocumentPickerResponse } from 'screens/BenefitsScreen/BenefitsStackScreens' import { AppDispatch } from 'store' import { ErrorObject } from 'store/api' @@ -422,3 +424,59 @@ export function fullPanelCardStyleInterpolator({ overlayStyle: { opacity: overlayOpacity }, } } + +/** + * When passed a string of text this function will identify if it has any PII + * that will need to be replaced within it + * Checks for: + * Phone Number + * SSN + * email/mailto + * @param body - String to check for PII + * @returns either a boolean or the edited string + */ +export function checkStringForPII(body: string): { found: boolean; newText: string } { + let found = false + let newText = '' + let phoneMatch, ssnMatch, emailMatch, mailToMatch + const whiteSpace = body + .trim() + .split(/\S/) + .reverse() + .filter((value) => value !== '') + const bodySplit = body.split(/\s/).filter((value) => value !== '') + _.forEach(bodySplit, (text) => { + phoneMatch = PHONE_REGEX_EXP.exec(text) + ssnMatch = SSN_REGEX_EXP.exec(text) + emailMatch = EMAIL_REGEX_EXP.exec(text) + mailToMatch = MAIL_TO_REGEX_EXP.exec(text) + if (phoneMatch) { + found = true + text = '###-###-####' + } else if (ssnMatch) { + found = true + text = '###-##-####' + } else if (emailMatch || mailToMatch) { + found = true + text = 'xxxxxxx@xxx.xxx' + } + // if (index !== 0 && index !== bodySplit.length - 1) { + // //checking phone/ssn by concating several split texts for white space seperators. + // const previousText = bodySplit[index - 1] + // const nextText = bodySplit[index + 1] + // const testString = previousText + ' ' + text + ' ' + nextText + // phoneMatch = PHONE_REGEX_EXP.exec(testString) + // ssnMatch = SSN_REGEX_EXP.exec(testString) + // if (phoneMatch) { + // found = true + // text = '###-###-####' + // } else if (ssnMatch) { + // found = true + // text = '###-##-####' + // } + // } + newText = newText.concat(text) + newText = newText.concat(whiteSpace.pop() || '') + }) + return { found, newText } +} From b5404fce8fe4d6791d0a6db250a2d7e4a3e79257 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Mon, 25 Nov 2024 10:58:09 -0500 Subject: [PATCH 02/16] removed console logs --- VAMobile/src/utils/common.ts | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/VAMobile/src/utils/common.ts b/VAMobile/src/utils/common.ts index 4ded47a242c..f8f3f59edf9 100644 --- a/VAMobile/src/utils/common.ts +++ b/VAMobile/src/utils/common.ts @@ -460,21 +460,6 @@ export function checkStringForPII(body: string): { found: boolean; newText: stri found = true text = 'xxxxxxx@xxx.xxx' } - // if (index !== 0 && index !== bodySplit.length - 1) { - // //checking phone/ssn by concating several split texts for white space seperators. - // const previousText = bodySplit[index - 1] - // const nextText = bodySplit[index + 1] - // const testString = previousText + ' ' + text + ' ' + nextText - // phoneMatch = PHONE_REGEX_EXP.exec(testString) - // ssnMatch = SSN_REGEX_EXP.exec(testString) - // if (phoneMatch) { - // found = true - // text = '###-###-####' - // } else if (ssnMatch) { - // found = true - // text = '###-##-####' - // } - // } newText = newText.concat(text) newText = newText.concat(whiteSpace.pop() || '') }) From 8e9ff728d8d3c29e3462d03234a94cba79a11dc2 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Mon, 25 Nov 2024 10:58:16 -0500 Subject: [PATCH 03/16] removed console logs --- .../SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx index a030113d1c9..22455026f92 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx @@ -32,7 +32,6 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { const { found, newText } = checkStringForPII(task) // logAnalyticsEvent(Events.vama_feedback_submitted(taskCompleted, satisfaction)) if (found) { - console.log('Before task: ', task) Alert.alert('Please Remove PII', 'We detected something that seems like PII, please remove it to continue', [ { text: 'Return to feedback', @@ -43,7 +42,6 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { text: 'submit anyways', onPress: () => { setTaskOverride(newText) - console.log('After task: ', task) navigation.goBack() }, }, From 768adaf77c09c92d1051432f3aa2686fd9157032 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Tue, 26 Nov 2024 12:07:20 -0500 Subject: [PATCH 04/16] edited content --- .../InAppFeedbackScreen/InAppFeedbackScreen.tsx | 8 ++++---- VAMobile/src/translations/en/common.json | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx index 22455026f92..a0697269668 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx @@ -32,18 +32,18 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { const { found, newText } = checkStringForPII(task) // logAnalyticsEvent(Events.vama_feedback_submitted(taskCompleted, satisfaction)) if (found) { - Alert.alert('Please Remove PII', 'We detected something that seems like PII, please remove it to continue', [ + Alert.alert(t('inAppFeedback.personalInfo.title'), t('inAppFeedback.personalInfo.body'), [ { - text: 'Return to feedback', + text: t('inAppFeedback.personalInfo.edit'), style: 'cancel', - onPress: () => {}, }, { - text: 'submit anyways', + text: t('inAppFeedback.personalInfo.submit'), onPress: () => { setTaskOverride(newText) navigation.goBack() }, + style: 'default', }, ]) } else { diff --git a/VAMobile/src/translations/en/common.json b/VAMobile/src/translations/en/common.json index 11652c38008..f42acb93a3d 100644 --- a/VAMobile/src/translations/en/common.json +++ b/VAMobile/src/translations/en/common.json @@ -843,6 +843,10 @@ "inAppFeedback.legalReqs.paragraph.2": "Information gathered will be kept private to the extent provided by law.", "inAppFeedback.legalReqs.paragraph.link": "Get valid control numbers on OMB website", "inAppFeedback.submitFeedback": "Submit feedback", + "inAppFeedback.personalInfo.title": "Submit your feedback with personal information?", + "inAppFeedback.personalInfo.body": "You can still submit your feedback. But we recommend deleting any personal information you included.", + "inAppFeedback.personalInfo.edit": "Edit feedback", + "inAppFeedback.personalInfo.submit": "Submit anyway", "inAppRecruitment.contracts": "VA contracts: 36C10B22C0011 & 36C10X18C0061", "inAppRecruitment.goToQuestionnaire": "Go to questionnaire", "inAppRecruitment.goToQuestionnaire.loading": "Loading questionnaire...", From f6aa87af3577973880cd55ff1f0f3410b1f875f7 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Fri, 29 Nov 2024 11:26:14 -0500 Subject: [PATCH 05/16] finished trigger for refill request --- .../src/api/prescriptions/requestRefills.tsx | 2 +- VAMobile/src/utils/inAppReviews.tsx | 35 +++++++++++++++++-- VAMobile/src/utils/remoteConfig.test.ts | 1 + VAMobile/src/utils/remoteConfig.ts | 3 ++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/VAMobile/src/api/prescriptions/requestRefills.tsx b/VAMobile/src/api/prescriptions/requestRefills.tsx index e959395f5ec..1267e3985fc 100644 --- a/VAMobile/src/api/prescriptions/requestRefills.tsx +++ b/VAMobile/src/api/prescriptions/requestRefills.tsx @@ -40,7 +40,7 @@ export const useRequestRefills = () => { const prescriptionIds = variables.map((prescription) => prescription.id) logAnalyticsEvent(Events.vama_rx_refill_success(prescriptionIds)) queryClient.invalidateQueries({ queryKey: prescriptionKeys.prescriptions }) - registerReviewEvent() + registerReviewEvent(false, 'refillRequest') }, onError: (error, variables) => { const prescriptionIds = variables.map((prescription) => prescription.id) diff --git a/VAMobile/src/utils/inAppReviews.tsx b/VAMobile/src/utils/inAppReviews.tsx index 1d7515a2b18..77b973bb188 100644 --- a/VAMobile/src/utils/inAppReviews.tsx +++ b/VAMobile/src/utils/inAppReviews.tsx @@ -6,17 +6,48 @@ import { Events } from 'constants/analytics' import { logAnalyticsEvent } from './analytics' import { getVersionName } from './deviceData' +import { useGiveFeedback } from './hooks' import { featureEnabled } from './remoteConfig' import { requestReview } from './rnReviews' export const STORAGE_REVIEW_EVENT_KEY = '@review_event' +export const STORAGE_FEEDBACK_EVENT_KEY = '@feedback_event_' export const STORAGE_LAST_REVIEW_PROMPT_DATE_MILLIS = '@last_review_date' +export const STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS = '@last_feedback_date' export const STORAGE_LAST_REVIEW_VERSION = '@last_review_version' export const IN_APP_REVIEW_INTERVAL_DAYS = 122 +export const IN_APP_FEEDBACK_INTERVAL_DAYS = 30 export const IN_APP_REVIEW_ACTIONS_THRESHOLD = 7 +export const IN_APP_FEEDBACK_ACTIONS_THRESHOLD = 3 -export const registerReviewEvent = async (screenView?: boolean): Promise => { - if (!featureEnabled('inAppReview')) return +export const registerReviewEvent = async (screenView?: boolean, feedbackScreen?: string): Promise => { + const inAppFeedback = useGiveFeedback() + if (!featureEnabled('inAppReview') && !featureEnabled('inAppFeedback')) return + //Checked for feedbackScreen triggers first. + if (featureEnabled('inAppFeedback') && feedbackScreen) { + let feedbackKey = STORAGE_FEEDBACK_EVENT_KEY.concat(feedbackScreen) + const feedbackCount = await AsyncStorage.getItem(STORAGE_FEEDBACK_EVENT_KEY.concat(feedbackScreen)) + const totalFeedback = feedbackCount ? parseInt(feedbackCount, 10) + 1 : 1 + //always increment the count when a feedback screen is registered + await AsyncStorage.setItem(feedbackKey, `${totalFeedback}`) + //check if this register would prompt for feedback + if (totalFeedback >= IN_APP_FEEDBACK_ACTIONS_THRESHOLD) { + //this date does not need to be feedbackScreen specific based on AC's: + //'Do not display feedback if user has submitted feedback for any feature within the past 30 days' + const lastFeedback = await AsyncStorage.getItem(STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS) + //doesn't prompt for feedback if feedback has been given in past 30 days. If prompt for feedback, return and skip potential in app review + if ( + (lastFeedback && + DateTime.fromMillis(parseInt(lastFeedback, 10)).diffNow('days').days > IN_APP_FEEDBACK_INTERVAL_DAYS) || + !lastFeedback + ) { + inAppFeedback(feedbackScreen) + await AsyncStorage.setItem(feedbackKey, '0') + await AsyncStorage.setItem(STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS, `${DateTime.now().millisecond}`) + return + } + } + } const prev = await AsyncStorage.getItem(STORAGE_REVIEW_EVENT_KEY) const total = prev ? parseInt(prev, 10) + 1 : 1 await AsyncStorage.setItem(STORAGE_REVIEW_EVENT_KEY, `${total}`) diff --git a/VAMobile/src/utils/remoteConfig.test.ts b/VAMobile/src/utils/remoteConfig.test.ts index f80de88dc3c..0ebfc5c62b9 100644 --- a/VAMobile/src/utils/remoteConfig.test.ts +++ b/VAMobile/src/utils/remoteConfig.test.ts @@ -23,6 +23,7 @@ const mockOverrides = { decisionLettersWaygate: false, haptics: false, homeScreenPrefetch: false, + inAppFeedback: false, inAppRecruitment: false, inAppReview: true, inAppUpdates: false, diff --git a/VAMobile/src/utils/remoteConfig.ts b/VAMobile/src/utils/remoteConfig.ts index 279f5af0d20..fb20fa3267f 100644 --- a/VAMobile/src/utils/remoteConfig.ts +++ b/VAMobile/src/utils/remoteConfig.ts @@ -22,6 +22,7 @@ export type FeatureToggleType = | 'haptics' | 'homeScreenPrefetch' | 'inAppRecruitment' + | 'inAppFeedback' | 'inAppReview' | 'inAppUpdates' | 'patientCheckIn' @@ -41,6 +42,7 @@ type FeatureToggleValues = { haptics: boolean homeScreenPrefetch: boolean inAppRecruitment: boolean + inAppFeedback: boolean inAppReview: boolean inAppUpdates: boolean patientCheckIn: boolean @@ -61,6 +63,7 @@ export const defaults: FeatureToggleValues = { haptics: true, homeScreenPrefetch: true, inAppRecruitment: false, + inAppFeedback: false, inAppReview: true, inAppUpdates: true, patientCheckIn: false, From f09951f8c50b159ae629fea45045f2e4d13794b6 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Mon, 2 Dec 2024 12:42:45 -0500 Subject: [PATCH 06/16] changing to useReviewEvent --- .../api/appointments/cancelAppointment.tsx | 4 +- .../api/contactInformation/deleteEmail.tsx | 3 +- .../api/contactInformation/saveAddress.tsx | 3 +- .../src/api/contactInformation/saveEmail.tsx | 3 +- .../contactInformation/savePhoneNumber.tsx | 3 +- .../downloadDecisionLetter.tsx | 3 +- .../api/demographics/updateGenderIdentity.tsx | 3 +- .../api/demographics/updatePreferredName.tsx | 3 +- .../src/api/directDeposit/updateBankInfo.tsx | 3 +- VAMobile/src/api/letters/downloadLetter.tsx | 3 +- .../src/api/prescriptions/requestRefills.tsx | 5 +- .../src/api/secureMessaging/saveDraft.tsx | 3 +- .../src/api/secureMessaging/sendMessage.tsx | 3 +- .../AppealDetailsScreen.tsx | 7 +- .../ClaimDetailsScreen/ClaimDetailsScreen.tsx | 7 +- .../DisabilityRatingsScreen.tsx | 7 +- .../PastAppointmentDetails.tsx | 7 +- .../UpcomingAppointmentDetails.tsx | 7 +- .../PrescriptionDetails.tsx | 7 +- .../RefillTrackingDetails.tsx | 7 +- .../ViewMessage/ViewMessageScreen.tsx | 7 +- .../ContactInformationScreen.tsx | 5 +- .../PersonalInformationScreen.tsx | 5 +- .../VeteranStatusScreen.tsx | 5 +- .../PaymentDetailsScreen.tsx | 7 +- VAMobile/src/utils/inAppReviews.tsx | 81 ++++++++++--------- 26 files changed, 115 insertions(+), 86 deletions(-) diff --git a/VAMobile/src/api/appointments/cancelAppointment.tsx b/VAMobile/src/api/appointments/cancelAppointment.tsx index cdb8f223ef0..0c9a34c7c0a 100644 --- a/VAMobile/src/api/appointments/cancelAppointment.tsx +++ b/VAMobile/src/api/appointments/cancelAppointment.tsx @@ -6,7 +6,7 @@ import { DEFAULT_UPCOMING_DAYS_LIMIT, TimeFrameTypeConstants } from 'constants/a import { put } from 'store/api' import { logNonFatalErrorToFirebase } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { appointmentsKeys } from './queryKeys' @@ -30,7 +30,7 @@ const cancelAppointment = (cancelID: string) => { */ export const useCancelAppointment = () => { const queryClient = useQueryClient() - + const registerReviewEvent = useReviewEvent() return useMutation({ mutationFn: cancelAppointment, onSuccess(_, variables) { diff --git a/VAMobile/src/api/contactInformation/deleteEmail.tsx b/VAMobile/src/api/contactInformation/deleteEmail.tsx index 64f235ccb1e..161bd464faa 100644 --- a/VAMobile/src/api/contactInformation/deleteEmail.tsx +++ b/VAMobile/src/api/contactInformation/deleteEmail.tsx @@ -5,7 +5,7 @@ import { Events, UserAnalytics } from 'constants/analytics' import { Params as APIParams, EditResponseData, del } from 'store/api' import { logAnalyticsEvent, logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { contactInformationKeys } from './queryKeys' @@ -20,6 +20,7 @@ const deleteEmail = (emailData: EmailData) => { * Returns a mutation for deleting an email */ export const useDeleteEmail = () => { + const registerReviewEvent = useReviewEvent() const queryClient = useQueryClient() return useMutation({ diff --git a/VAMobile/src/api/contactInformation/saveAddress.tsx b/VAMobile/src/api/contactInformation/saveAddress.tsx index d46b837d376..c585833281a 100644 --- a/VAMobile/src/api/contactInformation/saveAddress.tsx +++ b/VAMobile/src/api/contactInformation/saveAddress.tsx @@ -5,7 +5,7 @@ import { Events, UserAnalytics } from 'constants/analytics' import { Params as APIParams, EditResponseData, post, put } from 'store/api' import { logAnalyticsEvent, logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { contactInformationKeys } from './queryKeys' import { validateAddress } from './validateAddress' @@ -32,6 +32,7 @@ export const saveAddress = async ({ addressData, revalidate }: SaveAddressParame * Returns a mutation for saving an address */ export const useSaveAddress = () => { + const registerReviewEvent = useReviewEvent() const queryClient = useQueryClient() return useMutation({ diff --git a/VAMobile/src/api/contactInformation/saveEmail.tsx b/VAMobile/src/api/contactInformation/saveEmail.tsx index e6f26f6e4e2..fbd683c2ba4 100644 --- a/VAMobile/src/api/contactInformation/saveEmail.tsx +++ b/VAMobile/src/api/contactInformation/saveEmail.tsx @@ -5,7 +5,7 @@ import { Events, UserAnalytics } from 'constants/analytics' import { Params as APIParams, EditResponseData, post, put } from 'store/api' import { logAnalyticsEvent, logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { contactInformationKeys } from './queryKeys' @@ -26,6 +26,7 @@ const saveEmail = (emailData: SaveEmailData) => { * Returns a mutation for saving an email */ export const useSaveEmail = () => { + const registerReviewEvent = useReviewEvent() const queryClient = useQueryClient() return useMutation({ diff --git a/VAMobile/src/api/contactInformation/savePhoneNumber.tsx b/VAMobile/src/api/contactInformation/savePhoneNumber.tsx index 0eb91a55b67..38ec6b93960 100644 --- a/VAMobile/src/api/contactInformation/savePhoneNumber.tsx +++ b/VAMobile/src/api/contactInformation/savePhoneNumber.tsx @@ -5,7 +5,7 @@ import { Events, UserAnalytics } from 'constants/analytics' import { Params as APIParams, EditResponseData, post, put } from 'store/api' import { logAnalyticsEvent, logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { contactInformationKeys } from './queryKeys' @@ -26,6 +26,7 @@ const savePhoneNumber = (phoneData: PhoneData) => { * Returns a mutation for saving a phone number */ export const useSavePhoneNumber = () => { + const registerReviewEvent = useReviewEvent() const queryClient = useQueryClient() return useMutation({ diff --git a/VAMobile/src/api/decisionLetters/downloadDecisionLetter.tsx b/VAMobile/src/api/decisionLetters/downloadDecisionLetter.tsx index b707c33e2dc..23b4beb0a2d 100644 --- a/VAMobile/src/api/decisionLetters/downloadDecisionLetter.tsx +++ b/VAMobile/src/api/decisionLetters/downloadDecisionLetter.tsx @@ -6,7 +6,7 @@ import store from 'store' import { DEMO_MODE_LETTER_ENDPOINT, DEMO_MODE_LETTER_NAME } from 'store/api/demo/letters' import getEnv from 'utils/env' import { downloadDemoFile, downloadFile } from 'utils/filesystem' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { decisionLettersKeys } from './queryKeys' @@ -16,6 +16,7 @@ const { API_ROOT } = getEnv() * Fetch user decision letter */ const downloadDecisionLetter = async (id: string): Promise => { + const registerReviewEvent = useReviewEvent() const escapedId = encodeURI(id) // escape chars like {} in document ID const decisionLettersEndpoint = `${API_ROOT}/v0/claims/decision-letters/${escapedId}/download` const filePath = store.getState().demo.demoMode diff --git a/VAMobile/src/api/demographics/updateGenderIdentity.tsx b/VAMobile/src/api/demographics/updateGenderIdentity.tsx index 7dc00acb194..c4a573bc8fa 100644 --- a/VAMobile/src/api/demographics/updateGenderIdentity.tsx +++ b/VAMobile/src/api/demographics/updateGenderIdentity.tsx @@ -4,7 +4,7 @@ import { Events, UserAnalytics } from 'constants/analytics' import { put } from 'store/api' import { logAnalyticsEvent, logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { demographicsKeys } from './queryKeys' @@ -19,6 +19,7 @@ const updateGenderIdentity = (genderIdentity: string) => { * Returns a mutation for updating gender identity */ export const useUpdateGenderIdentity = () => { + const registerReviewEvent = useReviewEvent() const queryClient = useQueryClient() return useMutation({ diff --git a/VAMobile/src/api/demographics/updatePreferredName.tsx b/VAMobile/src/api/demographics/updatePreferredName.tsx index ebf11905572..6ed209611a2 100644 --- a/VAMobile/src/api/demographics/updatePreferredName.tsx +++ b/VAMobile/src/api/demographics/updatePreferredName.tsx @@ -4,7 +4,7 @@ import { Events, UserAnalytics } from 'constants/analytics' import { put } from 'store/api' import { logAnalyticsEvent, logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { demographicsKeys } from './queryKeys' @@ -22,6 +22,7 @@ const updatePreferredName = (preferredName: string) => { * Returns a mutation for updating preferred name */ export const useUpdatePreferredName = () => { + const registerReviewEvent = useReviewEvent() const queryClient = useQueryClient() return useMutation({ diff --git a/VAMobile/src/api/directDeposit/updateBankInfo.tsx b/VAMobile/src/api/directDeposit/updateBankInfo.tsx index 69eb5d8eaac..d0450509059 100644 --- a/VAMobile/src/api/directDeposit/updateBankInfo.tsx +++ b/VAMobile/src/api/directDeposit/updateBankInfo.tsx @@ -12,7 +12,7 @@ import { DemoState } from 'store/slices/demoSlice' import { logAnalyticsEvent, logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' import { getErrorKeys } from 'utils/errors' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { directDepositKeys } from './queryKeys' @@ -28,6 +28,7 @@ const updateBankInfo = (paymentAccountData: PaymentAccountData) => { * Returns a mutation for updating direct deposit information */ export const useUpdateBankInfo = () => { + const registerReviewEvent = useReviewEvent() const queryClient = useQueryClient() const { demoMode } = useSelector((state) => state.demo) diff --git a/VAMobile/src/api/letters/downloadLetter.tsx b/VAMobile/src/api/letters/downloadLetter.tsx index be234faca9c..eaa79ab145e 100644 --- a/VAMobile/src/api/letters/downloadLetter.tsx +++ b/VAMobile/src/api/letters/downloadLetter.tsx @@ -10,7 +10,7 @@ import { DEMO_MODE_LETTER_ENDPOINT, DEMO_MODE_LETTER_NAME } from 'store/api/demo import { logAnalyticsEvent, setAnalyticsUserProperty } from 'utils/analytics' import getEnv from 'utils/env' import { downloadDemoFile, downloadFile } from 'utils/filesystem' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { lettersKeys } from './queryKeys' @@ -23,6 +23,7 @@ const downloadLetter = async ( letterType: LetterTypes, lettersOption: LettersDownloadParams, ): Promise => { + const registerReviewEvent = useReviewEvent() const lettersAPI = `${API_ROOT}/v0/letters/${letterType}/download` const filePath = store.getState().demo.demoMode ? await downloadDemoFile(DEMO_MODE_LETTER_ENDPOINT, DEMO_MODE_LETTER_NAME, lettersOption as unknown as Params) diff --git a/VAMobile/src/api/prescriptions/requestRefills.tsx b/VAMobile/src/api/prescriptions/requestRefills.tsx index 1267e3985fc..b1309d063a5 100644 --- a/VAMobile/src/api/prescriptions/requestRefills.tsx +++ b/VAMobile/src/api/prescriptions/requestRefills.tsx @@ -5,7 +5,7 @@ import { Events, UserAnalytics } from 'constants/analytics' import { put } from 'store/api' import { logAnalyticsEvent, logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { prescriptionKeys } from './queryKeys' @@ -30,6 +30,7 @@ const requestRefills = async (prescriptions: PrescriptionsList): Promise { + const registerReviewEvent = useReviewEvent(false, 'refillRequest') const queryClient = useQueryClient() return useMutation({ mutationFn: requestRefills, @@ -40,7 +41,7 @@ export const useRequestRefills = () => { const prescriptionIds = variables.map((prescription) => prescription.id) logAnalyticsEvent(Events.vama_rx_refill_success(prescriptionIds)) queryClient.invalidateQueries({ queryKey: prescriptionKeys.prescriptions }) - registerReviewEvent(false, 'refillRequest') + registerReviewEvent() }, onError: (error, variables) => { const prescriptionIds = variables.map((prescription) => prescription.id) diff --git a/VAMobile/src/api/secureMessaging/saveDraft.tsx b/VAMobile/src/api/secureMessaging/saveDraft.tsx index 28fd2cb0da6..b99e8a8f7cc 100644 --- a/VAMobile/src/api/secureMessaging/saveDraft.tsx +++ b/VAMobile/src/api/secureMessaging/saveDraft.tsx @@ -5,7 +5,7 @@ import { UserAnalytics } from 'constants/analytics' import { Params, post, put } from 'store/api' import { logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { secureMessagingKeys } from './queryKeys' @@ -28,6 +28,7 @@ const saveDraft = ({ messageID, replyID, messageData }: SaveDraftParameters) => * Returns a mutation for saving a draft message */ export const useSaveDraft = () => { + const registerReviewEvent = useReviewEvent() const queryClient = useQueryClient() return useMutation({ mutationFn: saveDraft, diff --git a/VAMobile/src/api/secureMessaging/sendMessage.tsx b/VAMobile/src/api/secureMessaging/sendMessage.tsx index 03c6bb3d3ad..4daaf22d7a7 100644 --- a/VAMobile/src/api/secureMessaging/sendMessage.tsx +++ b/VAMobile/src/api/secureMessaging/sendMessage.tsx @@ -5,7 +5,7 @@ import { UserAnalytics } from 'constants/analytics' import { Params, contentTypes, post } from 'store/api' import { logNonFatalErrorToFirebase, setAnalyticsUserProperty } from 'utils/analytics' import { isErrorObject } from 'utils/common' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { secureMessagingKeys } from './queryKeys' @@ -58,6 +58,7 @@ const sendMessage = ({ messageData, replyToID, uploads }: SendMessageParameters) * Returns a mutation for sending a message */ export const useSendMessage = () => { + const registerReviewEvent = useReviewEvent() const queryClient = useQueryClient() return useMutation({ mutationFn: sendMessage, diff --git a/VAMobile/src/screens/BenefitsScreen/ClaimsScreen/AppealDetailsScreen/AppealDetailsScreen.tsx b/VAMobile/src/screens/BenefitsScreen/ClaimsScreen/AppealDetailsScreen/AppealDetailsScreen.tsx index d3cc73f0a15..478e1d58f66 100644 --- a/VAMobile/src/screens/BenefitsScreen/ClaimsScreen/AppealDetailsScreen/AppealDetailsScreen.tsx +++ b/VAMobile/src/screens/BenefitsScreen/ClaimsScreen/AppealDetailsScreen/AppealDetailsScreen.tsx @@ -16,7 +16,7 @@ import { ScreenIDTypesConstants } from 'store/api/types/Screens' import { logAnalyticsEvent } from 'utils/analytics' import { formatDateMMMMDDYYYY, getFormattedTimeForTimeZone, getTranslation } from 'utils/formattingUtils' import { useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { screenContentAllowed } from 'utils/waygateConfig' import NeedHelpData from '../NeedHelpData/NeedHelpData' @@ -28,6 +28,7 @@ type AppealDetailsScreenProps = StackScreenProps { if (appeal && !loadingAppeal && !appealError) { - registerReviewEvent(true) + registerReviewEvent() } - }, [appeal, loadingAppeal, appealError]) + }, [appeal, loadingAppeal, appealError, registerReviewEvent]) const onTabChange = (tab: number) => { setSelectedTab(tab) diff --git a/VAMobile/src/screens/BenefitsScreen/ClaimsScreen/ClaimDetailsScreen/ClaimDetailsScreen.tsx b/VAMobile/src/screens/BenefitsScreen/ClaimsScreen/ClaimDetailsScreen/ClaimDetailsScreen.tsx index 167dca2a69f..d39a1d754dc 100644 --- a/VAMobile/src/screens/BenefitsScreen/ClaimsScreen/ClaimDetailsScreen/ClaimDetailsScreen.tsx +++ b/VAMobile/src/screens/BenefitsScreen/ClaimsScreen/ClaimDetailsScreen/ClaimDetailsScreen.tsx @@ -37,7 +37,7 @@ import { logAnalyticsEvent } from 'utils/analytics' import { isDisabilityCompensationClaim, numberOfItemsNeedingAttentionFromVet } from 'utils/claims' import { formatDateMMMMDDYYYY } from 'utils/formattingUtils' import { useBeforeNavBackListener, useRouteNavigation, useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { featureEnabled } from 'utils/remoteConfig' import { screenContentAllowed } from 'utils/waygateConfig' @@ -64,6 +64,7 @@ function ClaimDetailsScreen({ navigation, route }: ClaimDetailsScreenProps) { const [downloadFile, setDownloadFile] = useState(false) const { claimID, claimType } = route.params + const registerReviewEvent = useReviewEvent(true) const queryClient = useQueryClient() const { data: claim, @@ -117,7 +118,7 @@ function ClaimDetailsScreen({ navigation, route }: ClaimDetailsScreenProps) { useEffect(() => { if (claim && !loadingClaim && !claimError) { - registerReviewEvent(true) + registerReviewEvent() logAnalyticsEvent( Events.vama_claim_details_open( claimID, @@ -133,7 +134,7 @@ function ClaimDetailsScreen({ navigation, route }: ClaimDetailsScreenProps) { // Keep tab switching or panel opening from triggering autoscroll setScrollIsEnabled(false) } - }, [claim, loadingClaim, claimError, claimID, attributes]) + }, [claim, loadingClaim, claimError, claimID, attributes, registerReviewEvent]) useEffect(() => { if (claimType === ClaimTypeConstants.ACTIVE && claim) { diff --git a/VAMobile/src/screens/BenefitsScreen/DisabilityRatingsScreen/DisabilityRatingsScreen.tsx b/VAMobile/src/screens/BenefitsScreen/DisabilityRatingsScreen/DisabilityRatingsScreen.tsx index 7a7c053b73e..ffb56d81bda 100644 --- a/VAMobile/src/screens/BenefitsScreen/DisabilityRatingsScreen/DisabilityRatingsScreen.tsx +++ b/VAMobile/src/screens/BenefitsScreen/DisabilityRatingsScreen/DisabilityRatingsScreen.tsx @@ -25,7 +25,7 @@ import { a11yLabelVA } from 'utils/a11yLabel' import getEnv from 'utils/env' import { capitalizeFirstLetter, displayedTextPhoneNumber } from 'utils/formattingUtils' import { useDowntime, useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { screenContentAllowed } from 'utils/waygateConfig' import NoDisabilityRatings from './NoDisabilityRatings/NoDisabilityRatings' @@ -34,6 +34,7 @@ function DisabilityRatingsScreen() { const theme = useTheme() const { t } = useTranslation(NAMESPACE.COMMON) const navigation = useNavigation() + const registerReviewEvent = useReviewEvent(true) const { LINK_URL_ABOUT_DISABILITY_RATINGS } = getEnv() const { condensedMarginBetween, contentMarginBottom, gutter } = theme.dimensions @@ -57,8 +58,8 @@ function DisabilityRatingsScreen() { useFocusEffect( React.useCallback(() => { - registerReviewEvent(true) - }, []), + registerReviewEvent() + }, [registerReviewEvent]), ) const individualRatingsList: Array = ratingData?.individualRatings || [] diff --git a/VAMobile/src/screens/HealthScreen/Appointments/PastAppointments/PastAppointmentDetails.tsx b/VAMobile/src/screens/HealthScreen/Appointments/PastAppointments/PastAppointmentDetails.tsx index 0e6f7100e6d..4873e2cc04f 100644 --- a/VAMobile/src/screens/HealthScreen/Appointments/PastAppointments/PastAppointmentDetails.tsx +++ b/VAMobile/src/screens/HealthScreen/Appointments/PastAppointments/PastAppointmentDetails.tsx @@ -8,7 +8,7 @@ import { FeatureLandingTemplate } from 'components' import { Events, UserAnalytics } from 'constants/analytics' import { NAMESPACE } from 'constants/namespaces' import { logAnalyticsEvent, setAnalyticsUserProperty } from 'utils/analytics' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { AppointmentDetailsSubTypeConstants, @@ -33,6 +33,7 @@ type PastAppointmentDetailsProps = StackScreenProps { if (!getApptError && appointmentNotFound) { diff --git a/VAMobile/src/screens/HealthScreen/Pharmacy/PrescriptionDetails/PrescriptionDetails.tsx b/VAMobile/src/screens/HealthScreen/Pharmacy/PrescriptionDetails/PrescriptionDetails.tsx index 917d3301007..58200f7be57 100644 --- a/VAMobile/src/screens/HealthScreen/Pharmacy/PrescriptionDetails/PrescriptionDetails.tsx +++ b/VAMobile/src/screens/HealthScreen/Pharmacy/PrescriptionDetails/PrescriptionDetails.tsx @@ -18,7 +18,7 @@ import { a11yLabelVA } from 'utils/a11yLabel' import { logAnalyticsEvent, setAnalyticsUserProperty } from 'utils/analytics' import getEnv from 'utils/env' import { useDestructiveActionSheet, useDowntime, useExternalLink, useRouteNavigation, useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { RefillTag, getDateTextAndLabel, getRxNumberTextAndLabel } from '../PrescriptionCommon' import DetailsTextSections from './DetailsTextSections' @@ -34,6 +34,7 @@ function PrescriptionDetails({ route, navigation }: PrescriptionDetailsProps) { const launchExternalLink = useExternalLink() const submitRefillAlert = useDestructiveActionSheet() const navigateTo = useRouteNavigation() + const registerReviewEvent = useReviewEvent(true) const prescriptionInDowntime = useDowntime(DowntimeFeatureTypeConstants.rx) const { t } = useTranslation(NAMESPACE.COMMON) const noneNoted = t('noneNoted') @@ -60,8 +61,8 @@ function PrescriptionDetails({ route, navigation }: PrescriptionDetailsProps) { useFocusEffect( React.useCallback(() => { setAnalyticsUserProperty(UserAnalytics.vama_uses_rx()) - registerReviewEvent(true) - }, []), + registerReviewEvent() + }, [registerReviewEvent]), ) const redirectLink = (): void => { diff --git a/VAMobile/src/screens/HealthScreen/Pharmacy/RefillTrackingDetails/RefillTrackingDetails.tsx b/VAMobile/src/screens/HealthScreen/Pharmacy/RefillTrackingDetails/RefillTrackingDetails.tsx index 271aee9dc30..2738decf43d 100644 --- a/VAMobile/src/screens/HealthScreen/Pharmacy/RefillTrackingDetails/RefillTrackingDetails.tsx +++ b/VAMobile/src/screens/HealthScreen/Pharmacy/RefillTrackingDetails/RefillTrackingDetails.tsx @@ -27,7 +27,7 @@ import { a11yLabelID, a11yLabelVA } from 'utils/a11yLabel' import { logAnalyticsEvent } from 'utils/analytics' import getEnv from 'utils/env' import { useBeforeNavBackListener, useDowntime, useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { screenContentAllowed } from 'utils/waygateConfig' import { HealthStackParamList } from '../../HealthStackScreens' @@ -57,6 +57,7 @@ const getTrackingLink = (deliveryService: string): string => { function RefillTrackingDetails({ route, navigation }: RefillTrackingDetailsProps) { const { prescription } = route.params const prescriptionInDowntime = useDowntime(DowntimeFeatureTypeConstants.rx) + const registerReviewEvent = useReviewEvent(true) const { data: trackingInfo, isFetching: loadingTrackingInfo, @@ -76,8 +77,8 @@ function RefillTrackingDetails({ route, navigation }: RefillTrackingDetailsProps useFocusEffect( React.useCallback(() => { - registerReviewEvent(true) - }, []), + registerReviewEvent() + }, [registerReviewEvent]), ) const renderOtherPrescription = (otherPrescriptions: Array) => { diff --git a/VAMobile/src/screens/HealthScreen/SecureMessaging/ViewMessage/ViewMessageScreen.tsx b/VAMobile/src/screens/HealthScreen/SecureMessaging/ViewMessage/ViewMessageScreen.tsx index f4b215db10a..48b252029ae 100644 --- a/VAMobile/src/screens/HealthScreen/SecureMessaging/ViewMessage/ViewMessageScreen.tsx +++ b/VAMobile/src/screens/HealthScreen/SecureMessaging/ViewMessage/ViewMessageScreen.tsx @@ -52,7 +52,7 @@ import { GenerateFolderMessage } from 'translations/en/functions' import { logAnalyticsEvent, setAnalyticsUserProperty } from 'utils/analytics' import { showSnackBar } from 'utils/common' import { useAppDispatch, useDowntimeByScreenID, useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { getfolderName } from 'utils/secureMessaging' import { screenContentAllowed } from 'utils/waygateConfig' @@ -108,6 +108,7 @@ function ViewMessageScreen({ route, navigation }: ViewMessageScreenProps) { const { t } = useTranslation(NAMESPACE.COMMON) const theme = useTheme() const dispatch = useAppDispatch() + const registerReviewEvent = useReviewEvent(true) const queryClient = useQueryClient() const { demoMode } = useSelector((state) => state.demo) @@ -168,9 +169,9 @@ function ViewMessageScreen({ route, navigation }: ViewMessageScreenProps) { useEffect(() => { if (threadFetched) { setAnalyticsUserProperty(UserAnalytics.vama_uses_sm()) - registerReviewEvent(true) + registerReviewEvent() } - }, [threadFetched]) + }, [threadFetched, registerReviewEvent]) useEffect(() => { if (messageFetched && currentFolderIdParam === SecureMessagingSystemFolderIdConstants.INBOX && currentPage) { diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/ContactInformationScreen/ContactInformationScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/ContactInformationScreen/ContactInformationScreen.tsx index ceaa6a07e90..ce5d429750e 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/ContactInformationScreen/ContactInformationScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/ContactInformationScreen/ContactInformationScreen.tsx @@ -30,7 +30,7 @@ import { ScreenIDTypesConstants } from 'store/api/types' import { a11yLabelVA } from 'utils/a11yLabel' import { logAnalyticsEvent } from 'utils/analytics' import { useDowntimeByScreenID, useRouteNavigation, useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { screenContentAllowed } from 'utils/waygateConfig' const getTextForPhoneData = ( @@ -134,6 +134,7 @@ function ContactInformationScreen({ navigation }: ContactInformationScreenProps) refetch: refetchContactInformation, failureCount, } = useContactInformation({ enabled: screenContentAllowed('WG_ContactInformation') }) + const registerReviewEvent = useReviewEvent(true) const contactInformationInDowntime = useDowntimeByScreenID(ScreenIDTypesConstants.CONTACT_INFORMATION_SCREEN_ID) const { contentMarginBottom, gutter, condensedMarginBetween } = theme.dimensions const [retried, setRetried] = useState(false) @@ -155,7 +156,7 @@ function ContactInformationScreen({ navigation }: ContactInformationScreenProps) const [reviewEventRegistered, setReviewEventRegistered] = useState(false) if (!reviewEventRegistered) { console.debug('REVIEW EVENT REGISTERED') - registerReviewEvent(true) + registerReviewEvent() setReviewEventRegistered(true) } diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/PersonalInformationScreen/PersonalInformationScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/PersonalInformationScreen/PersonalInformationScreen.tsx index e55df48754e..658d0f37314 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/PersonalInformationScreen/PersonalInformationScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/PersonalInformationScreen/PersonalInformationScreen.tsx @@ -25,7 +25,7 @@ import { ScreenIDTypesConstants } from 'store/api/types' import { a11yLabelVA } from 'utils/a11yLabel' import { stringToTitleCase } from 'utils/formattingUtils' import { useDowntimeByScreenID, useRouteNavigation, useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { featureEnabled } from 'utils/remoteConfig' import { screenContentAllowed } from 'utils/waygateConfig' @@ -62,6 +62,7 @@ function PersonalInformationScreen({ navigation }: PersonalInformationScreenProp const { gutter, condensedMarginBetween, formMarginBetween } = theme.dimensions const personalInformationInDowntime = useDowntimeByScreenID(ScreenIDTypesConstants.PERSONAL_INFORMATION_SCREEN_ID) const isScreenContentAllowed = screenContentAllowed('WG_PersonalInformation') + const registerReviewEvent = useReviewEvent(true) const { data: personalInfo, isFetching: loadingPersonalInfo, @@ -86,7 +87,7 @@ function PersonalInformationScreen({ navigation }: PersonalInformationScreenProp /** IN-App review events need to be recorded once, so we use the setState hook to guard this **/ const [reviewEventRegistered, setReviewEventRegistered] = useState(false) if (!reviewEventRegistered) { - registerReviewEvent(true) + registerReviewEvent() setReviewEventRegistered(true) } diff --git a/VAMobile/src/screens/HomeScreen/VeteranStatusScreen/VeteranStatusScreen.tsx b/VAMobile/src/screens/HomeScreen/VeteranStatusScreen/VeteranStatusScreen.tsx index d917054cb56..2aaa9f897bd 100644 --- a/VAMobile/src/screens/HomeScreen/VeteranStatusScreen/VeteranStatusScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/VeteranStatusScreen/VeteranStatusScreen.tsx @@ -24,7 +24,7 @@ import { import { NAMESPACE } from 'constants/namespaces' import { HomeStackParamList } from 'screens/HomeScreen/HomeStackScreens' import { useBeforeNavBackListener, useOrientation, useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { displayedTextPhoneNumber } from '../../../utils/formattingUtils' @@ -39,6 +39,7 @@ function VeteranStatusScreen({ navigation }: VeteranStatusScreenProps) { const { data: ratingData } = useDisabilityRating() const { data: userAuthorizedServices } = useAuthorizedServices() const { data: personalInfo } = usePersonalInformation() + const registerReviewEvent = useReviewEvent(true) const accessToMilitaryInfo = userAuthorizedServices?.militaryServiceHistory && serviceHistory.length > 0 const theme = useTheme() const { t } = useTranslation(NAMESPACE.COMMON) @@ -50,7 +51,7 @@ function VeteranStatusScreen({ navigation }: VeteranStatusScreenProps) { : undefined useBeforeNavBackListener(navigation, () => { - registerReviewEvent(true) + registerReviewEvent() }) const getPeriodOfService: React.ReactNode = map(serviceHistory, (service: ServiceData) => { diff --git a/VAMobile/src/screens/PaymentsScreen/PaymentHistory/PaymentDetailsScreen/PaymentDetailsScreen.tsx b/VAMobile/src/screens/PaymentsScreen/PaymentHistory/PaymentDetailsScreen/PaymentDetailsScreen.tsx index e3febaf63e6..e5955b5b704 100644 --- a/VAMobile/src/screens/PaymentsScreen/PaymentHistory/PaymentDetailsScreen/PaymentDetailsScreen.tsx +++ b/VAMobile/src/screens/PaymentsScreen/PaymentHistory/PaymentDetailsScreen/PaymentDetailsScreen.tsx @@ -9,7 +9,7 @@ import { DIRECT_DEPOSIT } from 'constants/common' import { NAMESPACE } from 'constants/namespaces' import { formatDateUtc } from 'utils/formattingUtils' import { useRouteNavigation, useTheme } from 'utils/hooks' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { PaymentsStackParamList } from '../../PaymentsStackScreens' @@ -20,11 +20,12 @@ function PaymentDetailsScreen({ navigation, route }: PaymentDetailsScreenProps) const { t } = useTranslation(NAMESPACE.COMMON) const theme = useTheme() const navigateTo = useRouteNavigation() + const registerReviewEvent = useReviewEvent(true) useFocusEffect( React.useCallback(() => { - registerReviewEvent(true) - }, []), + registerReviewEvent() + }, [registerReviewEvent]), ) const placeHolder = t('noneNoted') diff --git a/VAMobile/src/utils/inAppReviews.tsx b/VAMobile/src/utils/inAppReviews.tsx index 77b973bb188..bcc852eba67 100644 --- a/VAMobile/src/utils/inAppReviews.tsx +++ b/VAMobile/src/utils/inAppReviews.tsx @@ -20,51 +20,56 @@ export const IN_APP_FEEDBACK_INTERVAL_DAYS = 30 export const IN_APP_REVIEW_ACTIONS_THRESHOLD = 7 export const IN_APP_FEEDBACK_ACTIONS_THRESHOLD = 3 -export const registerReviewEvent = async (screenView?: boolean, feedbackScreen?: string): Promise => { +export const useReviewEvent = (screenView?: boolean, feedbackScreen?: string): (() => Promise) => { const inAppFeedback = useGiveFeedback() - if (!featureEnabled('inAppReview') && !featureEnabled('inAppFeedback')) return - //Checked for feedbackScreen triggers first. - if (featureEnabled('inAppFeedback') && feedbackScreen) { - let feedbackKey = STORAGE_FEEDBACK_EVENT_KEY.concat(feedbackScreen) - const feedbackCount = await AsyncStorage.getItem(STORAGE_FEEDBACK_EVENT_KEY.concat(feedbackScreen)) - const totalFeedback = feedbackCount ? parseInt(feedbackCount, 10) + 1 : 1 - //always increment the count when a feedback screen is registered - await AsyncStorage.setItem(feedbackKey, `${totalFeedback}`) - //check if this register would prompt for feedback - if (totalFeedback >= IN_APP_FEEDBACK_ACTIONS_THRESHOLD) { - //this date does not need to be feedbackScreen specific based on AC's: - //'Do not display feedback if user has submitted feedback for any feature within the past 30 days' - const lastFeedback = await AsyncStorage.getItem(STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS) - //doesn't prompt for feedback if feedback has been given in past 30 days. If prompt for feedback, return and skip potential in app review - if ( - (lastFeedback && - DateTime.fromMillis(parseInt(lastFeedback, 10)).diffNow('days').days > IN_APP_FEEDBACK_INTERVAL_DAYS) || - !lastFeedback - ) { - inAppFeedback(feedbackScreen) - await AsyncStorage.setItem(feedbackKey, '0') - await AsyncStorage.setItem(STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS, `${DateTime.now().millisecond}`) - return + + const reviewEvent = async () => { + if (!featureEnabled('inAppReview') && !featureEnabled('inAppFeedback')) return + //Checked for feedbackScreen triggers first. + if (featureEnabled('inAppFeedback') && feedbackScreen) { + const feedbackKey = STORAGE_FEEDBACK_EVENT_KEY.concat(feedbackScreen) + const feedbackCount = await AsyncStorage.getItem(STORAGE_FEEDBACK_EVENT_KEY.concat(feedbackScreen)) + const totalFeedback = feedbackCount ? parseInt(feedbackCount, 10) + 1 : 1 + //always increment the count when a feedback screen is registered + await AsyncStorage.setItem(feedbackKey, `${totalFeedback}`) + //check if this register would prompt for feedback + if (totalFeedback >= IN_APP_FEEDBACK_ACTIONS_THRESHOLD) { + //this date does not need to be feedbackScreen specific based on AC's: + //'Do not display feedback if user has submitted feedback for any feature within the past 30 days' + const lastFeedback = await AsyncStorage.getItem(STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS) + //doesn't prompt for feedback if feedback has been given in past 30 days. If prompt for feedback, return and skip potential in app review + if ( + (lastFeedback && + DateTime.fromMillis(parseInt(lastFeedback, 10)).diffNow('days').days > IN_APP_FEEDBACK_INTERVAL_DAYS) || + !lastFeedback + ) { + inAppFeedback(feedbackScreen) + await AsyncStorage.setItem(feedbackKey, '0') + await AsyncStorage.setItem(STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS, `${DateTime.now().millisecond}`) + return + } } } - } - const prev = await AsyncStorage.getItem(STORAGE_REVIEW_EVENT_KEY) - const total = prev ? parseInt(prev, 10) + 1 : 1 - await AsyncStorage.setItem(STORAGE_REVIEW_EVENT_KEY, `${total}`) - const versionName = await getVersionName() - if (!screenView && total >= IN_APP_REVIEW_ACTIONS_THRESHOLD) { - const lastReview = await AsyncStorage.getItem(STORAGE_LAST_REVIEW_PROMPT_DATE_MILLIS) - if (!lastReview) { - await callReviewAPI(versionName) - } else { - const days = DateTime.fromMillis(parseInt(lastReview, 10)).diffNow('days').days - const lastReviewVersion = await AsyncStorage.getItem(STORAGE_LAST_REVIEW_VERSION) - - if (days > IN_APP_REVIEW_INTERVAL_DAYS && lastReviewVersion !== versionName) { + const prev = await AsyncStorage.getItem(STORAGE_REVIEW_EVENT_KEY) + const total = prev ? parseInt(prev, 10) + 1 : 1 + await AsyncStorage.setItem(STORAGE_REVIEW_EVENT_KEY, `${total}`) + const versionName = await getVersionName() + if (!screenView && total >= IN_APP_REVIEW_ACTIONS_THRESHOLD) { + const lastReview = await AsyncStorage.getItem(STORAGE_LAST_REVIEW_PROMPT_DATE_MILLIS) + if (!lastReview) { await callReviewAPI(versionName) + } else { + const days = DateTime.fromMillis(parseInt(lastReview, 10)).diffNow('days').days + const lastReviewVersion = await AsyncStorage.getItem(STORAGE_LAST_REVIEW_VERSION) + + if (days > IN_APP_REVIEW_INTERVAL_DAYS && lastReviewVersion !== versionName) { + await callReviewAPI(versionName) + } } } } + + return reviewEvent } const callReviewAPI = async (versionName: string): Promise => { From 1015bc17c68d1251e28be2f0f8c61baf98b5a995 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Tue, 3 Dec 2024 09:10:21 -0500 Subject: [PATCH 07/16] fixed fileviewer examples --- .../claimsAndAppeals/downloadEFolderDocument.tsx | 13 +++++++++---- .../api/decisionLetters/downloadDecisionLetter.tsx | 8 ++++---- VAMobile/src/api/letters/downloadLetter.tsx | 7 ++++--- 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/VAMobile/src/api/claimsAndAppeals/downloadEFolderDocument.tsx b/VAMobile/src/api/claimsAndAppeals/downloadEFolderDocument.tsx index 13a87ff846c..43acad02003 100644 --- a/VAMobile/src/api/claimsAndAppeals/downloadEFolderDocument.tsx +++ b/VAMobile/src/api/claimsAndAppeals/downloadEFolderDocument.tsx @@ -6,7 +6,7 @@ import store from 'store' import { DEMO_MODE_LETTER_ENDPOINT } from 'store/api/demo/letters' import getEnv from 'utils/env' import { downloadDemoFile, downloadFile } from 'utils/filesystem' -import { registerReviewEvent } from 'utils/inAppReviews' +import { useReviewEvent } from 'utils/inAppReviews' import { claimsAndAppealsKeys } from './queryKeys' @@ -15,14 +15,18 @@ const { API_ROOT } = getEnv() /** * Fetch user E Folder Document */ -const downloadEFolderDocument = async (id: string, fileName: string): Promise => { +const downloadEFolderDocument = async ( + id: string, + fileName: string, + func: () => Promise, +): Promise => { const eFolderDocumentAPI = `${API_ROOT}/v0/efolder/documents/${id}/download?file_name=${fileName}}` const filePath = store.getState().demo.demoMode ? await downloadDemoFile(DEMO_MODE_LETTER_ENDPOINT, fileName) : await downloadFile('POST', eFolderDocumentAPI, fileName, undefined, 1) if (filePath) { - await FileViewer.open(filePath, { onDismiss: () => registerReviewEvent() }) + await FileViewer.open(filePath, { onDismiss: () => func() }) return true } } @@ -31,10 +35,11 @@ const downloadEFolderDocument = async (id: string, fileName: string): Promise { + const registerReviewEvent = useReviewEvent(false) return useQuery({ enabled: false, queryKey: [claimsAndAppealsKeys.eFolderDownloadDoc, id, fileName], - queryFn: () => downloadEFolderDocument(id, fileName), + queryFn: () => downloadEFolderDocument(id, fileName, registerReviewEvent), meta: { errorName: 'downloadEFolderDocument: Service error', }, diff --git a/VAMobile/src/api/decisionLetters/downloadDecisionLetter.tsx b/VAMobile/src/api/decisionLetters/downloadDecisionLetter.tsx index 23b4beb0a2d..11a75a69ebb 100644 --- a/VAMobile/src/api/decisionLetters/downloadDecisionLetter.tsx +++ b/VAMobile/src/api/decisionLetters/downloadDecisionLetter.tsx @@ -15,15 +15,14 @@ const { API_ROOT } = getEnv() /** * Fetch user decision letter */ -const downloadDecisionLetter = async (id: string): Promise => { - const registerReviewEvent = useReviewEvent() +const downloadDecisionLetter = async (id: string, func: () => Promise): Promise => { const escapedId = encodeURI(id) // escape chars like {} in document ID const decisionLettersEndpoint = `${API_ROOT}/v0/claims/decision-letters/${escapedId}/download` const filePath = store.getState().demo.demoMode ? await downloadDemoFile(DEMO_MODE_LETTER_ENDPOINT, DEMO_MODE_LETTER_NAME) : await downloadFile('GET', decisionLettersEndpoint, 'decision_letter.pdf', undefined, 3) if (filePath) { - await FileViewer.open(filePath, { onDismiss: () => registerReviewEvent() }) + await FileViewer.open(filePath, { onDismiss: () => func() }) return true } } @@ -32,10 +31,11 @@ const downloadDecisionLetter = async (id: string): Promise * Returns a query for a user decision letter */ export const useDownloadDecisionLetter = (id: string, options?: { enabled?: boolean }) => { + const registerReviewEvent = useReviewEvent(false) return useQuery({ ...options, queryKey: [decisionLettersKeys.downloadLetter, id], - queryFn: () => downloadDecisionLetter(id), + queryFn: () => downloadDecisionLetter(id, registerReviewEvent), meta: { errorName: 'downloadDecisionLetter: Service error', }, diff --git a/VAMobile/src/api/letters/downloadLetter.tsx b/VAMobile/src/api/letters/downloadLetter.tsx index eaa79ab145e..72a3dd2c71d 100644 --- a/VAMobile/src/api/letters/downloadLetter.tsx +++ b/VAMobile/src/api/letters/downloadLetter.tsx @@ -22,8 +22,8 @@ const { API_ROOT } = getEnv() const downloadLetter = async ( letterType: LetterTypes, lettersOption: LettersDownloadParams, + func: () => Promise, ): Promise => { - const registerReviewEvent = useReviewEvent() const lettersAPI = `${API_ROOT}/v0/letters/${letterType}/download` const filePath = store.getState().demo.demoMode ? await downloadDemoFile(DEMO_MODE_LETTER_ENDPOINT, DEMO_MODE_LETTER_NAME, lettersOption as unknown as Params) @@ -31,7 +31,7 @@ const downloadLetter = async ( if (filePath) { logAnalyticsEvent(Events.vama_letter_download(letterType)) setAnalyticsUserProperty(UserAnalytics.vama_uses_letters()) - await FileViewer.open(filePath, { onDismiss: () => registerReviewEvent() }) + await FileViewer.open(filePath, { onDismiss: () => func() }) return true } } @@ -40,10 +40,11 @@ const downloadLetter = async ( * Returns a query for a user letter */ export const useDownloadLetter = (letterType: LetterTypes, lettersOption: LettersDownloadParams) => { + const registerReviewEvent = useReviewEvent(false) return useQuery({ enabled: false, queryKey: [lettersKeys.downloadLetter, letterType, lettersOption], - queryFn: () => downloadLetter(letterType, lettersOption), + queryFn: () => downloadLetter(letterType, lettersOption, registerReviewEvent), meta: { errorName: 'downloadLetter: Service error', }, From a1823e06c8cf47771de57e74d0d4e68d7a0a4968 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Tue, 3 Dec 2024 10:03:30 -0500 Subject: [PATCH 08/16] added analytics --- VAMobile/src/constants/analytics.ts | 38 +++++++++---------- .../InAppFeedbackScreen.tsx | 20 +++++++--- VAMobile/src/utils/inAppReviews.tsx | 1 + 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/VAMobile/src/constants/analytics.ts b/VAMobile/src/constants/analytics.ts index d4da9bea452..2f77c24e987 100644 --- a/VAMobile/src/constants/analytics.ts +++ b/VAMobile/src/constants/analytics.ts @@ -635,25 +635,25 @@ export const Events = { name: 'vama_gender_id_success', } }, - // vama_feedback_page_entered: (): Event => { - // return { - // name: 'vama_feedback_page_entered', - // } - // }, - // vama_feedback_page_closed: (): Event => { - // return { - // name: 'vama_feedback_page_closed', - // } - // }, - // vama_feedback_submitted: (taskCompleted: string, satisfaction: string): Event => { - // return { - // name: 'vama_feedback_submitted', - // params: { - // taskCompleted, - // satisfaction, - // }, - // } - // }, + vama_feedback_page_ent: (): Event => { + return { + name: 'vama_feedback_page_ent', + } + }, + vama_feedback_page_exit: (): Event => { + return { + name: 'vama_feedback_page_exit', + } + }, + vama_feedback_submitted: (taskCompleted: string, satisfaction: string): Event => { + return { + name: 'vama_feedback_submitted', + params: { + taskCompleted, + satisfaction, + }, + } + }, vama_givefb_close: (screenName: string): Event => { return { name: 'vama_givefb_close', diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx index a0697269668..5f88c8d7068 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx @@ -8,10 +8,12 @@ import { Button } from '@department-of-veterans-affairs/mobile-component-library import { RootNavStackParamList } from 'App' import { BorderColorVariant, Box, LargePanel, RadioGroup, RadioGroupProps, TextView, VATextInput } from 'components' +import { Events } from 'constants/analytics' import { NAMESPACE } from 'constants/namespaces' +import { logAnalyticsEvent } from 'utils/analytics' import { checkStringForPII } from 'utils/common' import getEnv from 'utils/env' -import { useExternalLink, useTheme } from 'utils/hooks' +import { useBeforeNavBackListener, useExternalLink, useTheme } from 'utils/hooks' const { LINK_URL_OMB_PAGE } = getEnv() @@ -24,13 +26,15 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { const [task, setTaskOverride] = useState('') const launchExternalLink = useExternalLink() - // useBeforeNavBackListener(navigation, () => { - // logAnalyticsEvent(Events.vama_feedback_page_closed()) - // }) + useBeforeNavBackListener(navigation, () => { + logAnalyticsEvent(Events.vama_feedback_page_exit()) + }) const onSubmit = (): void => { const { found, newText } = checkStringForPII(task) - // logAnalyticsEvent(Events.vama_feedback_submitted(taskCompleted, satisfaction)) + console.log('found: ', found) + console.log('task: ', task) + console.log('newText: ', newText) if (found) { Alert.alert(t('inAppFeedback.personalInfo.title'), t('inAppFeedback.personalInfo.body'), [ { @@ -40,13 +44,17 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { { text: t('inAppFeedback.personalInfo.submit'), onPress: () => { - setTaskOverride(newText) + console.log('task: ', task) + console.log('newText: ', newText) + logAnalyticsEvent(Events.vama_feedback_submitted(newText, satisfaction)) navigation.goBack() }, style: 'default', }, ]) } else { + console.log('task: ', task) + logAnalyticsEvent(Events.vama_feedback_submitted(task, satisfaction)) navigation.goBack() } } diff --git a/VAMobile/src/utils/inAppReviews.tsx b/VAMobile/src/utils/inAppReviews.tsx index bcc852eba67..c6dace4e665 100644 --- a/VAMobile/src/utils/inAppReviews.tsx +++ b/VAMobile/src/utils/inAppReviews.tsx @@ -43,6 +43,7 @@ export const useReviewEvent = (screenView?: boolean, feedbackScreen?: string): ( DateTime.fromMillis(parseInt(lastFeedback, 10)).diffNow('days').days > IN_APP_FEEDBACK_INTERVAL_DAYS) || !lastFeedback ) { + logAnalyticsEvent(Events.vama_feedback_page_ent()) inAppFeedback(feedbackScreen) await AsyncStorage.setItem(feedbackKey, '0') await AsyncStorage.setItem(STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS, `${DateTime.now().millisecond}`) From a786b4fe9a7a3816d8b39a0dcbab2ff991b07695 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Tue, 3 Dec 2024 15:00:46 -0500 Subject: [PATCH 09/16] got exit working appropriately --- .../InAppFeedbackScreen/InAppFeedbackScreen.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx index bc5a46339e8..0825a3b4132 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx @@ -24,9 +24,13 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { const theme = useTheme() const [satisfaction, setSatisfaction] = useState('') const [task, setTaskOverride] = useState('') + let submittedCheck = false const launchExternalLink = useExternalLink() useBeforeNavBackListener(navigation, () => { + if (submittedCheck === true) { + return + } logAnalyticsEvent(Events.vama_feedback_page_exit()) }) @@ -42,6 +46,7 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { text: t('inAppFeedback.personalInfo.submit'), onPress: () => { logAnalyticsEvent(Events.vama_feedback_submitted(newText, satisfaction)) + submittedCheck = true navigation.goBack() }, style: 'default', @@ -49,6 +54,7 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { ]) } else { logAnalyticsEvent(Events.vama_feedback_submitted(task, satisfaction)) + submittedCheck = true navigation.goBack() } } From 0d5619f682481d8b150f08f85a609016f2b6aec7 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Tue, 3 Dec 2024 15:14:59 -0500 Subject: [PATCH 10/16] more Analytics Changes --- VAMobile/src/App.tsx | 2 +- VAMobile/src/constants/analytics.ts | 22 ++++++++++++++++--- .../InAppFeedbackScreen.tsx | 9 ++++---- VAMobile/src/utils/hooks/index.tsx | 5 ++++- VAMobile/src/utils/inAppReviews.tsx | 2 +- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/VAMobile/src/App.tsx b/VAMobile/src/App.tsx index bce892ba296..8e668a9ebc6 100644 --- a/VAMobile/src/App.tsx +++ b/VAMobile/src/App.tsx @@ -109,7 +109,7 @@ export type RootNavStackParamList = WebviewStackParams & { SubmitEvidenceSubtask: { claimID: string } - InAppFeedback: { task: string } + InAppFeedback: { screen: string } Tabs: undefined } diff --git a/VAMobile/src/constants/analytics.ts b/VAMobile/src/constants/analytics.ts index 2f77c24e987..0a2e495db45 100644 --- a/VAMobile/src/constants/analytics.ts +++ b/VAMobile/src/constants/analytics.ts @@ -635,20 +635,36 @@ export const Events = { name: 'vama_gender_id_success', } }, - vama_feedback_page_ent: (): Event => { + vama_feedback_page_ent: (screen: string): Event => { return { name: 'vama_feedback_page_ent', + params: { + screen, + }, } }, - vama_feedback_page_exit: (): Event => { + vama_feedback_ask: (screen: string, response: boolean): Event => { + return { + name: 'vama_feedback_ask', + params: { + screen, + response, + }, + } + }, + vama_feedback_closed: (screen: string): Event => { return { name: 'vama_feedback_page_exit', + params: { + screen, + }, } }, - vama_feedback_submitted: (taskCompleted: string, satisfaction: string): Event => { + vama_feedback_submitted: (screen: string, taskCompleted: string, satisfaction: string): Event => { return { name: 'vama_feedback_submitted', params: { + screen, taskCompleted, satisfaction, }, diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx index 0825a3b4132..29f3654107d 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx @@ -19,11 +19,12 @@ const { LINK_URL_OMB_PAGE } = getEnv() type InAppFeedbackScreenProps = StackScreenProps -function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { +function InAppFeedbackScreen({ navigation, route }: InAppFeedbackScreenProps) { const { t } = useTranslation(NAMESPACE.COMMON) const theme = useTheme() const [satisfaction, setSatisfaction] = useState('') const [task, setTaskOverride] = useState('') + const { screen } = route.params let submittedCheck = false const launchExternalLink = useExternalLink() @@ -31,7 +32,7 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { if (submittedCheck === true) { return } - logAnalyticsEvent(Events.vama_feedback_page_exit()) + logAnalyticsEvent(Events.vama_feedback_closed(screen)) }) const onSubmit = (): void => { @@ -45,7 +46,7 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { { text: t('inAppFeedback.personalInfo.submit'), onPress: () => { - logAnalyticsEvent(Events.vama_feedback_submitted(newText, satisfaction)) + logAnalyticsEvent(Events.vama_feedback_submitted(screen, newText, satisfaction)) submittedCheck = true navigation.goBack() }, @@ -53,7 +54,7 @@ function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) { }, ]) } else { - logAnalyticsEvent(Events.vama_feedback_submitted(task, satisfaction)) + logAnalyticsEvent(Events.vama_feedback_submitted(screen, task, satisfaction)) submittedCheck = true navigation.goBack() } diff --git a/VAMobile/src/utils/hooks/index.tsx b/VAMobile/src/utils/hooks/index.tsx index e791f04b1d2..7f280688f19 100644 --- a/VAMobile/src/utils/hooks/index.tsx +++ b/VAMobile/src/utils/hooks/index.tsx @@ -263,10 +263,13 @@ export function useGiveFeedback(): (task: string) => void { return (task: string) => { const onOKPress = () => { + logAnalyticsEvent(Events.vama_feedback_ask(task, true)) navigateTo('InAppFeedback', { task }) } - const onCancelPress = () => {} + const onCancelPress = () => { + logAnalyticsEvent(Events.vama_feedback_ask(task, false)) + } Alert.alert(t('inAppFeedback.popup.title'), t('inAppFeedback.popup.body'), [ { diff --git a/VAMobile/src/utils/inAppReviews.tsx b/VAMobile/src/utils/inAppReviews.tsx index c6dace4e665..426582e5768 100644 --- a/VAMobile/src/utils/inAppReviews.tsx +++ b/VAMobile/src/utils/inAppReviews.tsx @@ -43,7 +43,7 @@ export const useReviewEvent = (screenView?: boolean, feedbackScreen?: string): ( DateTime.fromMillis(parseInt(lastFeedback, 10)).diffNow('days').days > IN_APP_FEEDBACK_INTERVAL_DAYS) || !lastFeedback ) { - logAnalyticsEvent(Events.vama_feedback_page_ent()) + logAnalyticsEvent(Events.vama_feedback_page_ent(feedbackScreen)) inAppFeedback(feedbackScreen) await AsyncStorage.setItem(feedbackKey, '0') await AsyncStorage.setItem(STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS, `${DateTime.now().millisecond}`) From b4fecb4558532e9469c851eef78cd255691aa56c Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Tue, 3 Dec 2024 15:17:03 -0500 Subject: [PATCH 11/16] last analytic edit --- VAMobile/src/utils/inAppReviews.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/VAMobile/src/utils/inAppReviews.tsx b/VAMobile/src/utils/inAppReviews.tsx index 426582e5768..bcc852eba67 100644 --- a/VAMobile/src/utils/inAppReviews.tsx +++ b/VAMobile/src/utils/inAppReviews.tsx @@ -43,7 +43,6 @@ export const useReviewEvent = (screenView?: boolean, feedbackScreen?: string): ( DateTime.fromMillis(parseInt(lastFeedback, 10)).diffNow('days').days > IN_APP_FEEDBACK_INTERVAL_DAYS) || !lastFeedback ) { - logAnalyticsEvent(Events.vama_feedback_page_ent(feedbackScreen)) inAppFeedback(feedbackScreen) await AsyncStorage.setItem(feedbackKey, '0') await AsyncStorage.setItem(STORAGE_LAST_FEEDBACK_PROMPT_DATE_MILLIS, `${DateTime.now().millisecond}`) From 1bb8aee9236ac40a1ac3ee776b1b78a97fc22fb1 Mon Sep 17 00:00:00 2001 From: rbontrager Date: Tue, 3 Dec 2024 14:47:37 -0600 Subject: [PATCH 12/16] Test e2e mapping logic issue fix (will remove when done!) --- .github/workflows/e2e_detox_mapping.yml | 47 ++++++++++++++++--------- VAMobile/e2e/detoxMapping.json | 10 +++--- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/.github/workflows/e2e_detox_mapping.yml b/.github/workflows/e2e_detox_mapping.yml index ff3b7e0f0c4..fa1dbf5b869 100644 --- a/.github/workflows/e2e_detox_mapping.yml +++ b/.github/workflows/e2e_detox_mapping.yml @@ -60,6 +60,8 @@ jobs: - name: Check if directory/file is in detox mapping id: detox_mapping_check run: | + directoryFound="false" + noFileFound="false" fileNames=$(jq -r '.files' ${{ github.workspace }}/VAMobile/e2e/detoxMapping.json) directoryNames=$(jq -r '.directory' ${{ github.workspace }}/VAMobile/e2e/detoxMapping.json) for file in ${{steps.changed_files_file_name.outputs.all_changed_and_modified_files}}; do @@ -68,15 +70,22 @@ jobs: fileFound=$(echo $fileNames | jq --arg fileName "$baseFile" '.[$fileName]') if [[ "$fileFound" == "null" ]]; then fileDirectory=$(dirname $file) - baseDirectory=$(echo $fileDirectory | sed 's#.*/##') - baseDirectory=$(echo $baseDirectory | sed 's/ //g') - directoryFound=$(echo $directoryNames | jq --arg fileName "$baseDirectory" '.[$fileName]') - if [[ "$directoryFound" == "null" ]]; then + echo "$fileDirectory" + for directory in $(echo $directoryNames | jq -r 'keys | .[]'); do + if [[ $fileDirectory =~ $directory ]]; then + directoryFound="true" + break + fi + done + if [[ "$directoryFound" == "false" ]]; then echo "Missing File: $file or missing directory: $fileDirectory" - exit 1 + noFileFound="true" fi fi done + if [[ "$noFileFound" == "true" ]]; then + exit 1 + fi - name: Check if directory/file is spelled correctly id: detox_mapping_spell_check run: | @@ -131,17 +140,23 @@ jobs: fileFound=$(echo $fileNames | jq --arg fileName "$baseFile" '.[$fileName]') if [[ "$fileFound" == "null" ]]; then fileDirectory=$(dirname $file) - baseDirectory=$(echo $fileDirectory | sed 's#.*/##') - baseDirectory=$(echo $baseDirectory | sed 's/ //g') - directoryFound=$(echo $directoryNames | jq --arg fileName "$baseDirectory" '.[$fileName]') - if [[ "$firstInstanceFile" == "true" ]]; then - test_matrix=$directoryFound - test_matrix=$(echo $test_matrix | jq -c '.') - firstInstanceFile="false" - else - test_matrix=$(echo $test_matrix | jq -c '.') - test_matrix=$(echo $test_matrix | jq --argjson matrix "$directoryFound" '. += $matrix') - fi + echo "$fileDirectory" + for directory in $(echo $directoryNames | jq -r 'keys | .[]'); do + if [[ "$fileDirectory" =~ "$directory" ]]; then + echo "$directory" + directoryFound=$(echo $directoryNames | jq --arg fileName "$directory" -r '.[$fileName]') + echo "$directoryFound" + if [[ "$firstInstanceFile" == "true" ]]; then + test_matrix=$directoryFound + test_matrix=$(echo $test_matrix | jq -c '.') + firstInstanceFile="false" + else + test_matrix=$(echo $test_matrix | jq -c '.') + test_matrix=$(echo $test_matrix | jq --argjson matrix "$directoryFound" '. += $matrix') + fi + break + fi + done else if [[ "$firstInstanceFile" == "true" ]]; then test_matrix=$fileFound diff --git a/VAMobile/e2e/detoxMapping.json b/VAMobile/e2e/detoxMapping.json index 44ea6ce829f..f1d6c20283e 100644 --- a/VAMobile/e2e/detoxMapping.json +++ b/VAMobile/e2e/detoxMapping.json @@ -100,15 +100,12 @@ "ClaimsScreen": ["Appeals", "AppealsExpanded", "Claims"], "DisabilityRatingsScreen": ["DisabilityRatings", "VeteranStatusCard"], "Letters": ["VALetters"], - "BenefitsScreen": ["DisabilityRatings", "Claims", "Appeals", "VALetters"], - "HealthScreen": ["Appointments", "AppointmentsExpanded", "Cerner", "Prescriptions", "Messages", "VaccineRecords"], "Appointments": ["Appointments", "AppointmentsExpanded"], "CernerAlert": ["Cerner"], "HealthHelp": ["Cerner"], "Pharmacy": ["Prescriptions"], "SecureMessaging": ["Messages"], "Vaccines": ["VaccineRecords"], - "HomeScreen": ["HomeScreen", "ProfileScreen", "VeteranStatusCard"], "ContactVAScreen": ["HomeScreen"], "ProfileScreen": [ "ProfileScreen", @@ -122,14 +119,17 @@ "ContactInformationScreen": ["ContactInformation", "VALetters"], "MilitaryInformationScreen": ["MilitaryInformation", "VeteranStatusCard"], "PersonalInformationScreen": ["PersonalInformationScreen", "VeteranStatusCard", "HomeScreen", "ProfileScreen"], - "SettingsScreen": ["SettingsScreen"], "VeteransCrisisLineScreen": ["VeteransCrisisLine", "SignIn"], "VeteranStatusScreen": ["VeteranStatusCard"], "OnboardingCarousel": ["Onboarding"], - "PaymentsScreen": ["Payments", "DirectDeposit"], "DirectDepositScreen": ["DirectDeposit"], "PaymentHistory": ["Payments"], "SplashScreen": ["Onboarding", "LoginScreen"], + "BenefitsScreen": ["DisabilityRatings", "Claims", "Appeals", "VALetters"], + "HealthScreen": ["Appointments", "AppointmentsExpanded", "Cerner", "Prescriptions", "Messages", "VaccineRecords"], + "HomeScreen": ["HomeScreen", "ProfileScreen", "VeteranStatusCard"], + "SettingsScreen": ["SettingsScreen"], + "PaymentsScreen": ["Payments", "DirectDeposit"], "slices": [ "Appeals", "AppealsExpanded", From 8c8430964ee22532909f0f044b1a279577ee8447 Mon Sep 17 00:00:00 2001 From: rbontrager Date: Tue, 3 Dec 2024 14:55:07 -0600 Subject: [PATCH 13/16] Remove e2e mapping logic check --- .github/workflows/e2e_detox_mapping.yml | 47 +++++++++---------------- VAMobile/e2e/detoxMapping.json | 10 +++--- 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/.github/workflows/e2e_detox_mapping.yml b/.github/workflows/e2e_detox_mapping.yml index fa1dbf5b869..ff3b7e0f0c4 100644 --- a/.github/workflows/e2e_detox_mapping.yml +++ b/.github/workflows/e2e_detox_mapping.yml @@ -60,8 +60,6 @@ jobs: - name: Check if directory/file is in detox mapping id: detox_mapping_check run: | - directoryFound="false" - noFileFound="false" fileNames=$(jq -r '.files' ${{ github.workspace }}/VAMobile/e2e/detoxMapping.json) directoryNames=$(jq -r '.directory' ${{ github.workspace }}/VAMobile/e2e/detoxMapping.json) for file in ${{steps.changed_files_file_name.outputs.all_changed_and_modified_files}}; do @@ -70,22 +68,15 @@ jobs: fileFound=$(echo $fileNames | jq --arg fileName "$baseFile" '.[$fileName]') if [[ "$fileFound" == "null" ]]; then fileDirectory=$(dirname $file) - echo "$fileDirectory" - for directory in $(echo $directoryNames | jq -r 'keys | .[]'); do - if [[ $fileDirectory =~ $directory ]]; then - directoryFound="true" - break - fi - done - if [[ "$directoryFound" == "false" ]]; then + baseDirectory=$(echo $fileDirectory | sed 's#.*/##') + baseDirectory=$(echo $baseDirectory | sed 's/ //g') + directoryFound=$(echo $directoryNames | jq --arg fileName "$baseDirectory" '.[$fileName]') + if [[ "$directoryFound" == "null" ]]; then echo "Missing File: $file or missing directory: $fileDirectory" - noFileFound="true" + exit 1 fi fi done - if [[ "$noFileFound" == "true" ]]; then - exit 1 - fi - name: Check if directory/file is spelled correctly id: detox_mapping_spell_check run: | @@ -140,23 +131,17 @@ jobs: fileFound=$(echo $fileNames | jq --arg fileName "$baseFile" '.[$fileName]') if [[ "$fileFound" == "null" ]]; then fileDirectory=$(dirname $file) - echo "$fileDirectory" - for directory in $(echo $directoryNames | jq -r 'keys | .[]'); do - if [[ "$fileDirectory" =~ "$directory" ]]; then - echo "$directory" - directoryFound=$(echo $directoryNames | jq --arg fileName "$directory" -r '.[$fileName]') - echo "$directoryFound" - if [[ "$firstInstanceFile" == "true" ]]; then - test_matrix=$directoryFound - test_matrix=$(echo $test_matrix | jq -c '.') - firstInstanceFile="false" - else - test_matrix=$(echo $test_matrix | jq -c '.') - test_matrix=$(echo $test_matrix | jq --argjson matrix "$directoryFound" '. += $matrix') - fi - break - fi - done + baseDirectory=$(echo $fileDirectory | sed 's#.*/##') + baseDirectory=$(echo $baseDirectory | sed 's/ //g') + directoryFound=$(echo $directoryNames | jq --arg fileName "$baseDirectory" '.[$fileName]') + if [[ "$firstInstanceFile" == "true" ]]; then + test_matrix=$directoryFound + test_matrix=$(echo $test_matrix | jq -c '.') + firstInstanceFile="false" + else + test_matrix=$(echo $test_matrix | jq -c '.') + test_matrix=$(echo $test_matrix | jq --argjson matrix "$directoryFound" '. += $matrix') + fi else if [[ "$firstInstanceFile" == "true" ]]; then test_matrix=$fileFound diff --git a/VAMobile/e2e/detoxMapping.json b/VAMobile/e2e/detoxMapping.json index f1d6c20283e..44ea6ce829f 100644 --- a/VAMobile/e2e/detoxMapping.json +++ b/VAMobile/e2e/detoxMapping.json @@ -100,12 +100,15 @@ "ClaimsScreen": ["Appeals", "AppealsExpanded", "Claims"], "DisabilityRatingsScreen": ["DisabilityRatings", "VeteranStatusCard"], "Letters": ["VALetters"], + "BenefitsScreen": ["DisabilityRatings", "Claims", "Appeals", "VALetters"], + "HealthScreen": ["Appointments", "AppointmentsExpanded", "Cerner", "Prescriptions", "Messages", "VaccineRecords"], "Appointments": ["Appointments", "AppointmentsExpanded"], "CernerAlert": ["Cerner"], "HealthHelp": ["Cerner"], "Pharmacy": ["Prescriptions"], "SecureMessaging": ["Messages"], "Vaccines": ["VaccineRecords"], + "HomeScreen": ["HomeScreen", "ProfileScreen", "VeteranStatusCard"], "ContactVAScreen": ["HomeScreen"], "ProfileScreen": [ "ProfileScreen", @@ -119,17 +122,14 @@ "ContactInformationScreen": ["ContactInformation", "VALetters"], "MilitaryInformationScreen": ["MilitaryInformation", "VeteranStatusCard"], "PersonalInformationScreen": ["PersonalInformationScreen", "VeteranStatusCard", "HomeScreen", "ProfileScreen"], + "SettingsScreen": ["SettingsScreen"], "VeteransCrisisLineScreen": ["VeteransCrisisLine", "SignIn"], "VeteranStatusScreen": ["VeteranStatusCard"], "OnboardingCarousel": ["Onboarding"], + "PaymentsScreen": ["Payments", "DirectDeposit"], "DirectDepositScreen": ["DirectDeposit"], "PaymentHistory": ["Payments"], "SplashScreen": ["Onboarding", "LoginScreen"], - "BenefitsScreen": ["DisabilityRatings", "Claims", "Appeals", "VALetters"], - "HealthScreen": ["Appointments", "AppointmentsExpanded", "Cerner", "Prescriptions", "Messages", "VaccineRecords"], - "HomeScreen": ["HomeScreen", "ProfileScreen", "VeteranStatusCard"], - "SettingsScreen": ["SettingsScreen"], - "PaymentsScreen": ["Payments", "DirectDeposit"], "slices": [ "Appeals", "AppealsExpanded", From 594fc6a47616a972d811bd8109f18c821780bad4 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Wed, 4 Dec 2024 09:34:10 -0500 Subject: [PATCH 14/16] removed unused analytic --- VAMobile/src/constants/analytics.ts | 8 -------- .../SettingsScreen/DeveloperScreen/DeveloperScreen.tsx | 1 - 2 files changed, 9 deletions(-) diff --git a/VAMobile/src/constants/analytics.ts b/VAMobile/src/constants/analytics.ts index 0a2e495db45..6fcf30ddc1b 100644 --- a/VAMobile/src/constants/analytics.ts +++ b/VAMobile/src/constants/analytics.ts @@ -635,14 +635,6 @@ export const Events = { name: 'vama_gender_id_success', } }, - vama_feedback_page_ent: (screen: string): Event => { - return { - name: 'vama_feedback_page_ent', - params: { - screen, - }, - } - }, vama_feedback_ask: (screen: string, response: boolean): Event => { return { name: 'vama_feedback_ask', diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/DeveloperScreen/DeveloperScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/DeveloperScreen/DeveloperScreen.tsx index 3d0c0425eb1..54e919c660f 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/DeveloperScreen/DeveloperScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/DeveloperScreen/DeveloperScreen.tsx @@ -176,7 +176,6 @@ function DeveloperScreen({ navigation }: DeveloperScreenSettingsScreenProps) { ] const onFeedback = () => { - //logAnalyticsEvent(Events.vama_feedback_page_entered()) inAppFeedback('Developer') } From dc69f86ba1c5110727e25a4ec04830d1dc7a8694 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Wed, 4 Dec 2024 09:56:35 -0500 Subject: [PATCH 15/16] Added success snackbar --- .../InAppFeedbackScreen/InAppFeedbackScreen.tsx | 7 +++++-- VAMobile/src/translations/en/common.json | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx index 29f3654107d..6e79068807b 100644 --- a/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx +++ b/VAMobile/src/screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen.tsx @@ -11,9 +11,9 @@ import { BorderColorVariant, Box, LargePanel, RadioGroup, RadioGroupProps, TextV import { Events } from 'constants/analytics' import { NAMESPACE } from 'constants/namespaces' import { logAnalyticsEvent } from 'utils/analytics' -import { checkStringForPII } from 'utils/common' +import { checkStringForPII, showSnackBar } from 'utils/common' import getEnv from 'utils/env' -import { useBeforeNavBackListener, useExternalLink, useTheme } from 'utils/hooks' +import { useAppDispatch, useBeforeNavBackListener, useExternalLink, useTheme } from 'utils/hooks' const { LINK_URL_OMB_PAGE } = getEnv() @@ -24,6 +24,7 @@ function InAppFeedbackScreen({ navigation, route }: InAppFeedbackScreenProps) { const theme = useTheme() const [satisfaction, setSatisfaction] = useState('') const [task, setTaskOverride] = useState('') + const dispatch = useAppDispatch() const { screen } = route.params let submittedCheck = false const launchExternalLink = useExternalLink() @@ -49,6 +50,7 @@ function InAppFeedbackScreen({ navigation, route }: InAppFeedbackScreenProps) { logAnalyticsEvent(Events.vama_feedback_submitted(screen, newText, satisfaction)) submittedCheck = true navigation.goBack() + showSnackBar(t('inAppFeedback.snackbar.success'), dispatch, undefined, true, false, false) }, style: 'default', }, @@ -57,6 +59,7 @@ function InAppFeedbackScreen({ navigation, route }: InAppFeedbackScreenProps) { logAnalyticsEvent(Events.vama_feedback_submitted(screen, task, satisfaction)) submittedCheck = true navigation.goBack() + showSnackBar(t('inAppFeedback.snackbar.success'), dispatch, undefined, true, false, false) } } diff --git a/VAMobile/src/translations/en/common.json b/VAMobile/src/translations/en/common.json index cc7ce1f4c0c..6b0298d316b 100644 --- a/VAMobile/src/translations/en/common.json +++ b/VAMobile/src/translations/en/common.json @@ -847,6 +847,7 @@ "inAppFeedback.personalInfo.body": "You can still submit your feedback. But we recommend deleting any personal information you included.", "inAppFeedback.personalInfo.edit": "Edit feedback", "inAppFeedback.personalInfo.submit": "Submit anyway", + "inAppFeedback.snackbar.success": "Feedback sent", "inAppRecruitment.contracts": "VA contracts: 36C10B22C0011 & 36C10X18C0061", "inAppRecruitment.goToQuestionnaire": "Go to questionnaire", "inAppRecruitment.goToQuestionnaire.loading": "Loading questionnaire...", From 9614ae8e641a635286855977bc37f4585bbdd086 Mon Sep 17 00:00:00 2001 From: Jon Bindbeutel Date: Wed, 4 Dec 2024 11:00:00 -0500 Subject: [PATCH 16/16] Chris edit --- VAMobile/src/constants/analytics.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VAMobile/src/constants/analytics.ts b/VAMobile/src/constants/analytics.ts index 6fcf30ddc1b..56bd896faa9 100644 --- a/VAMobile/src/constants/analytics.ts +++ b/VAMobile/src/constants/analytics.ts @@ -646,7 +646,7 @@ export const Events = { }, vama_feedback_closed: (screen: string): Event => { return { - name: 'vama_feedback_page_exit', + name: 'vama_feedback_closed', params: { screen, },