Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spike binny in app feedback #10166

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions VAMobile/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
} from 'screens'
import { profileAddressType } from 'screens/HomeScreen/ProfileScreen/ContactInformationScreen/AddressSummary'
import EditAddressScreen from 'screens/HomeScreen/ProfileScreen/ContactInformationScreen/EditAddressScreen'
import InAppFeedbackScreen from 'screens/HomeScreen/ProfileScreen/SettingsScreen/InAppFeedbackScreen/InAppFeedbackScreen'
import BiometricsPreferenceScreen from 'screens/auth/BiometricsPreferenceScreen'
import RequestNotificationsScreen from 'screens/auth/RequestNotifications/RequestNotificationsScreen'
import store, { RootState } from 'store'
Expand Down Expand Up @@ -98,6 +99,7 @@ export type RootNavStackParamList = WebviewStackParams & {
EditDirectDeposit: {
displayTitle: string
}
InAppFeedback: { task: string }
Tabs: undefined
}

Expand Down Expand Up @@ -457,6 +459,7 @@ export function AuthedApp() {
component={EditDirectDepositScreen}
options={FULLSCREEN_SUBTASK_OPTIONS}
/>
<RootNavStack.Screen name="InAppFeedback" component={InAppFeedbackScreen} options={LARGE_PANEL_OPTIONS} />
{homeScreens}
{paymentsScreens}
{benefitsScreens}
Expand Down
19 changes: 19 additions & 0 deletions VAMobile/src/constants/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,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,
// },
// }
// },
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Committing these analytics commented out for the other ticket to provide.

vama_givefb_close: (screenName: string): Event => {
return {
name: 'vama_givefb_close',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import {
overrideLocalVersion,
setVersionSkipped,
} from 'utils/homeScreenAlerts'
import { useAlert, useAppDispatch, useRouteNavigation, useTheme } from 'utils/hooks'
import { useAlert, useAppDispatch, useGiveFeedback, useRouteNavigation, useTheme } from 'utils/hooks'
import { STORAGE_REVIEW_EVENT_KEY, resetReviewActionCount } from 'utils/inAppReviews'

type DeveloperScreenSettingsScreenProps = StackScreenProps<HomeStackParamList, 'Developer'>
Expand All @@ -52,6 +52,7 @@ function DeveloperScreen({ navigation }: DeveloperScreenSettingsScreenProps) {
const dispatch = useAppDispatch()
const navigateTo = useRouteNavigation()
const resetFirstTimeLoginAlert = useAlert()
const inAppFeedback = useGiveFeedback()
const [localVersionName, setVersionName] = useState<string>()
const [whatsNewLocalVersion, setWhatsNewVersion] = useState<string>()
const [skippedVersion, setSkippedVersionHomeScreen] = useState<string>()
Expand Down Expand Up @@ -174,6 +175,11 @@ function DeveloperScreen({ navigation }: DeveloperScreenSettingsScreenProps) {
},
]

const onFeedback = () => {
//logAnalyticsEvent(Events.vama_feedback_page_entered())
inAppFeedback('Developer')
}

return (
<FeatureLandingTemplate
backLabel={t('settings.title')}
Expand Down Expand Up @@ -202,6 +208,9 @@ function DeveloperScreen({ navigation }: DeveloperScreenSettingsScreenProps) {
</TextView>
</Box>
</TextArea>
<TextArea>
<Button onPress={onFeedback} label={'In App Feedback Screen'} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need a translation?

</TextArea>
</Box>
<Box>
<TextView
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'

import { StackScreenProps } from '@react-navigation/stack/lib/typescript/src/types'

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 { NAMESPACE } from 'constants/namespaces'
import { useTheme } from 'utils/hooks'

type InAppFeedbackScreenProps = StackScreenProps<RootNavStackParamList, 'InAppFeedback'>

function InAppFeedbackScreen({ navigation }: InAppFeedbackScreenProps) {
const { t } = useTranslation(NAMESPACE.COMMON)
const theme = useTheme()
const [satisfaction, setSatisfaction] = useState('')
const [task, setTaskOverride] = useState('')

// useBeforeNavBackListener(navigation, () => {
// logAnalyticsEvent(Events.vama_feedback_page_closed())
// })

const onChange = (value: string): void => {
setSatisfaction(value)
}

const onSubmit = (): void => {
// logAnalyticsEvent(Events.vama_feedback_submitted(taskCompleted, satisfaction))
navigation.goBack()
}

const radioGroupProps: RadioGroupProps<string> = {
isRadioList: false,
onChange: onChange,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can probably just be onChange: setSatisfaction

options: [
{
labelKey: t('inAppFeedback.overallSatisfaction.notAtAllSatisfied'),
value: t('inAppFeedback.overallSatisfaction.notAtAllSatisfied'),
},
{
labelKey: t('inAppFeedback.overallSatisfaction.dissatisfied'),
value: t('inAppFeedback.overallSatisfaction.dissatisfied'),
},
{
labelKey: t('inAppFeedback.overallSatisfaction.neither'),
value: t('inAppFeedback.overallSatisfaction.neither'),
},
{
labelKey: t('inAppFeedback.overallSatisfaction.satisfied'),
value: t('inAppFeedback.overallSatisfaction.satisfied'),
},
{
labelKey: t('inAppFeedback.overallSatisfaction.verySatisfied'),
value: t('inAppFeedback.overallSatisfaction.verySatisfied'),
},
],
value: satisfaction,
}

return (
<LargePanel title={t('inAppFeedback.title')} rightButtonText={t('close')}>
<Box mb={theme.dimensions.contentMarginBottom} mx={theme.dimensions.gutter}>
<TextView variant="MobileBodyBold" accessibilityRole="header">
{t('inAppFeedback.whatTask.header')}
</TextView>
<TextView variant="MobileBody" mb={theme.dimensions.alertBorderWidth}>
{t('inAppFeedback.whatTask.body')}
</TextView>
<VATextInput
inputType="none"
isTextArea={true}
value={task}
testID="AppFeedbackTaskID"
onChange={(val) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can probably simplify to onChange={setTaskOverride}

setTaskOverride(val)
}}
/>
<Box>
<TextView my={theme.dimensions.standardMarginBetween} variant="MobileBodyBold" accessibilityRole="header">
{t('inAppFeedback.overallSatisfaction.header')}
</TextView>
<RadioGroup {...radioGroupProps} />
</Box>
<Box mb={theme.dimensions.standardMarginBetween}>
<Button onPress={onSubmit} label={t('submit')} />
</Box>
<Box
borderTopWidth={theme.dimensions.borderWidth}
borderColor={theme.colors.border.prescriptionDivider as BorderColorVariant}>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this color be renamed if it's used in multiple places?

<TextView variant="HelperText" mt={theme.dimensions.standardMarginBetween}>
{t('inAppFeedback.legalReqs.number')}
</TextView>
<TextView variant="HelperText">{t('inAppFeedback.legalReqs.expiration')}</TextView>
<TextView variant="HelperText">{t('inAppFeedback.legalReqs.burdenTime')}</TextView>
<TextView variant="HelperText" mt={theme.dimensions.standardMarginBetween}>
{t('inAppFeedback.legalReqs.paragraph')}
</TextView>
</Box>
</Box>
</LargePanel>
)
}

export default InAppFeedbackScreen
24 changes: 23 additions & 1 deletion VAMobile/src/translations/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,25 @@
"howWillYou.useInfo.1": "We’ll use this information to contact you about certain benefits and services, like disability compensation, pension benefits, and claims and appeals.",
"howWillYou.useInfo.2": "If you’re enrolled in VA health care, we’ll send your prescriptions to your mailing address. Your health care team may also use this information to contact you.",
"icon.success": "Success icon,",
"inAppFeedback.title": "Give feedback",
"inAppFeedback.a11yHint": "Go to the give feedback page",
"inAppFeedback.popup.title": "Leave feedback?",
"inAppFeedback.popup.body": "Leaving us feedback helps us improve.",
"inAppFeedback.popup.notNow": "Not now",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could just use 'notNow' as the key

"inAppFeedback.popup.accept": "Give feedback",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding this translation twice, you could add it once with giveFeedback as the key

"inAppFeedback.whatTask.header": "What task were you trying to do today?",
"inAppFeedback.whatTask.body": "Please don't enter personal information into the text box. This includes your name, address, Social Security Number, medical information or anything else that someone could use to identify you.",
"inAppFeedback.taskSelection.header": "What task were you trying to do today?",
"inAppFeedback.overallSatisfaction.header": "What is your overall satisfaction with this app?",
"inAppFeedback.overallSatisfaction.notAtAllSatisfied": "Not at all satisfied",
"inAppFeedback.overallSatisfaction.dissatisfied": "Dissatisfied",
"inAppFeedback.overallSatisfaction.neither": "Neither satisfied or dissatisfied",
"inAppFeedback.overallSatisfaction.satisfied": "Satisfied",
"inAppFeedback.overallSatisfaction.verySatisfied": "Very satisfied",
"inAppFeedback.legalReqs.number": "OMB Number: 2900-0876",
"inAppFeedback.legalReqs.expiration": "Expiration: 02/28/2026",
"inAppFeedback.legalReqs.burdenTime": "Burden Time: 3 Minutes",
"inAppFeedback.legalReqs.paragraph": "VA may utilize individual Veteran survey data from this survey or other sources to ensure the final scores truly and accurately represent the experiences of Veterans. This information is collected in accordance with section 3507 of the Paperwork Reduction Act of 1995. Title 38, United States Code, allows us to ask for this information. We estimate that you will need an average of 3 minutes to review the instructions and complete this survey. The results of this survey will be used to inform opportunities for program improvement in the quality of VA services. Participation in this survey is voluntary, and your decision not to respond will have no impact on VA benefits or services which you may currently be receiving. VA cannot conduct or sponsor a collection of information unless a valid OMB control number is displayed. You are not required to respond to a collection of information if this number is not displayed. Valid OMB control numbers can be located on the OMB Internet Page at https://www.reginfo.gov/public/do/PRAMain. Information gathered will be kept private to the extent provided by law.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the link be clickable?

"inAppRecruitment.contracts": "VA contracts: 36C10B22C0011 & 36C10X18C0061",
"inAppRecruitment.giveFeedback": "Give feedback",
"inAppRecruitment.giveFeedback.a11yHint": "Go to the give feedback page",
Expand Down Expand Up @@ -931,6 +950,7 @@
"movedToThisStepOn": "Moved to this step on {{date}}",
"needed": "needed",
"next": "Next",
"no": "No",
"noActivity": "There's no activity to show.",
"noAppointments.visitVA": "Visit VA.gov",
"noAppointments.youCanSchedule": "You can schedule an appointment on VA.gov, or you can call your VA medical center to schedule an appointment.",
Expand Down Expand Up @@ -1378,6 +1398,7 @@
"statusDefinition.transferred": "A prescription moved to VA’s new electronic health record. This prescription may also be described as “Discontinued” on medication lists from your healthcare team. Take your medications as prescribed by your healthcare team.",
"statusDefinition.unknown": "The status cannot be determined. Contact your VA care team when you need more of this VA prescription. A prescription stopped by a VA provider. It is no longer available to be filled.",
"stepXofY": "Step {{current}} of {{total}}",
"submit": "Submit",
"success": "Success",
"sync.progress.signin": "Signing you in...",
"sync.progress.signout": "Signing you out...",
Expand Down Expand Up @@ -1474,5 +1495,6 @@
"webview.vagov": "va.gov",
"webview.valocation.loading": "Loading VA location finder...",
"whatsNew.dismissMessage": "Dismiss this message",
"whatsNew.title": "What's new"
"whatsNew.title": "What's new",
"yes": "Yes"
}
22 changes: 22 additions & 0 deletions VAMobile/src/utils/hooks/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,28 @@ export function useExternalLink(): (url: string, eventParams?: EventParams) => v
}
}

export function useGiveFeedback(): (task: string) => void {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider creating a constant to collect all the possible values in one place

const navigateTo = useRouteNavigation()
const { t } = useTranslation(NAMESPACE.COMMON)

return (task: string) => {
const onOKPress = () => {
navigateTo('InAppFeedback', { task })
}

const onCancelPress = () => {}

Alert.alert(t('inAppFeedback.popup.title'), t('inAppFeedback.popup.body'), [
{
text: t('inAppFeedback.popup.notNow'),
style: 'cancel',
onPress: onCancelPress,
},
{ text: t('inAppFeedback.popup.accept'), onPress: onOKPress, style: 'default' },
])
}
}

export type useDestructiveActionSheetButtonProps = {
/** text of button */
text: string
Expand Down
Loading