Skip to content

Commit

Permalink
Merge pull request Expensify#51136 from rushatgabhane/tour-fab
Browse files Browse the repository at this point in the history
[Self-guided tours][V3] Add tour link to FAB
  • Loading branch information
mountiny authored Nov 4, 2024
2 parents 9a577ee + 1c71ee6 commit 09032ea
Show file tree
Hide file tree
Showing 14 changed files with 151 additions and 80 deletions.
25 changes: 25 additions & 0 deletions assets/images/binoculars.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -879,8 +879,10 @@ const CONST = {
// Use Environment.getEnvironmentURL to get the complete URL with port number
DEV_NEW_EXPENSIFY_URL: 'https://dev.new.expensify.com:',
NAVATTIC: {
ADMIN_TOUR: 'https://expensify.navattic.com/kh204a7',
EMPLOYEE_TOUR: 'https://expensify.navattic.com/35609gb',
ADMIN_TOUR_PRODUCTION: 'https://expensify.navattic.com/kh204a7',
ADMIN_TOUR_STAGING: 'https://expensify.navattic.com/3i300k18',
EMPLOYEE_TOUR_PRODUCTION: 'https://expensify.navattic.com/35609gb',
EMPLOYEE_TOUR_STAGING: 'https://expensify.navattic.com/cf15002s',
},

OLDDOT_URLS: {
Expand Down
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import Bed from '@assets/images/bed.svg';
import Bell from '@assets/images/bell.svg';
import BellSlash from '@assets/images/bellSlash.svg';
import Bill from '@assets/images/bill.svg';
import Binoculars from '@assets/images/binoculars.svg';
import Bolt from '@assets/images/bolt.svg';
import Bookmark from '@assets/images/bookmark.svg';
import Box from '@assets/images/box.svg';
Expand Down Expand Up @@ -223,6 +224,7 @@ export {
Bill,
Bell,
BellSlash,
Binoculars,
Bolt,
Box,
Briefcase,
Expand Down
4 changes: 4 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5188,6 +5188,10 @@ const translations = {
emptySearchView: {
takeATour: 'Take a tour',
},
tour: {
takeATwoMinuteTour: 'Take a 2-minute tour',
exploreExpensify: 'Explore everything Expensify has to offer',
},
};

export default translations satisfies TranslationDeepObject<typeof translations>;
4 changes: 4 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5703,6 +5703,10 @@ const translations = {
emptySearchView: {
takeATour: 'Haz un tour',
},
tour: {
takeATwoMinuteTour: 'Haz un tour de 2 minutos',
exploreExpensify: 'Explora todo lo que Expensify tiene para ofrecer',
},
};

export default translations satisfies TranslationDeepObject<typeof en>;
2 changes: 2 additions & 0 deletions src/libs/API/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,7 @@ const WRITE_COMMANDS = {
SET_CARD_EXPORT_ACCOUNT: 'SetCardExportAccount',
SET_PERSONAL_DETAILS_AND_SHIP_EXPENSIFY_CARDS: 'SetPersonalDetailsAndShipExpensifyCards',
SET_INVOICING_TRANSFER_BANK_ACCOUNT: 'SetInvoicingTransferBankAccount',
SELF_TOUR_VIEWED: 'SelfTourViewed',
UPDATE_INVOICE_COMPANY_NAME: 'UpdateInvoiceCompanyName',
UPDATE_INVOICE_COMPANY_WEBSITE: 'UpdateInvoiceCompanyWebsite',
} as const;
Expand Down Expand Up @@ -861,6 +862,7 @@ type WriteCommandParameters = {
[WRITE_COMMANDS.UPDATE_CARD_SETTLEMENT_FREQUENCY]: Parameters.UpdateCardSettlementFrequencyParams;
[WRITE_COMMANDS.UPDATE_CARD_SETTLEMENT_ACCOUNT]: Parameters.UpdateCardSettlementAccountParams;
[WRITE_COMMANDS.SET_PERSONAL_DETAILS_AND_SHIP_EXPENSIFY_CARDS]: Parameters.SetPersonalDetailsAndShipExpensifyCardsParams;
[WRITE_COMMANDS.SELF_TOUR_VIEWED]: null;

// Xero API
[WRITE_COMMANDS.UPDATE_XERO_TENANT_ID]: Parameters.UpdateXeroGenericTypeParams;
Expand Down
14 changes: 14 additions & 0 deletions src/libs/TourUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type {ValueOf} from 'type-fest';
import CONST from '@src/CONST';
import type {OnboardingPurposeType} from '@src/CONST';

function getNavatticURL(environment: ValueOf<typeof CONST.ENVIRONMENT>, introSelected?: OnboardingPurposeType) {
const adminTourURL = environment === CONST.ENVIRONMENT.PRODUCTION ? CONST.NAVATTIC.ADMIN_TOUR_PRODUCTION : CONST.NAVATTIC.ADMIN_TOUR_STAGING;
const employeeTourURL = environment === CONST.ENVIRONMENT.PRODUCTION ? CONST.NAVATTIC.EMPLOYEE_TOUR_PRODUCTION : CONST.NAVATTIC.EMPLOYEE_TOUR_STAGING;
return introSelected === CONST.SELECTABLE_ONBOARDING_CHOICES.MANAGE_TEAM ? adminTourURL : employeeTourURL;
}

export {
// eslint-disable-next-line import/prefer-default-export
getNavatticURL,
};
17 changes: 16 additions & 1 deletion src/libs/actions/Welcome/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {NativeModules} from 'react-native';
import type {OnyxUpdate} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import * as API from '@libs/API';
import {SIDE_EFFECT_REQUEST_COMMANDS} from '@libs/API/types';
import {SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types';
import Log from '@libs/Log';
import type {OnboardingCompanySizeType, OnboardingPurposeType} from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -183,6 +183,20 @@ function resetAllChecks() {
OnboardingFlow.clearInitialPath();
}

function setSelfTourViewed() {
const optimisticData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: ONYXKEYS.NVP_ONBOARDING,
value: {
selfTourViewed: true,
},
},
];

API.write(WRITE_COMMANDS.SELF_TOUR_VIEWED, null, {optimisticData});
}

export {
onServerDataReady,
isOnboardingFlowCompleted,
Expand All @@ -195,4 +209,5 @@ export {
completeHybridAppOnboarding,
setOnboardingErrorMessage,
setOnboardingCompanySize,
setSelfTourViewed,
};
17 changes: 16 additions & 1 deletion src/libs/onboardingSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,19 @@ function hasCompletedHybridAppOnboardingFlowSelector(tryNewDotData: OnyxValue<ty
return completedHybridAppOnboarding;
}

export {hasCompletedGuidedSetupFlowSelector, hasCompletedHybridAppOnboardingFlowSelector};
/**
* Selector to get the value of selfTourViewed from the Onyx store
*
* `undefined` means the value is not loaded yet
* `true` means the user has completed the NewDot onboarding flow
* `false` means the user has not completed the NewDot onboarding flow
*/
function hasSeenTourSelector(onboarding: OnyxValue<typeof ONYXKEYS.NVP_ONBOARDING>): boolean | undefined {
if (Array.isArray(onboarding)) {
return false;
}

return onboarding?.selfTourViewed;
}

export {hasCompletedGuidedSetupFlowSelector, hasCompletedHybridAppOnboardingFlowSelector, hasSeenTourSelector};
9 changes: 6 additions & 3 deletions src/pages/Search/EmptySearchView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ import MenuItem from '@components/MenuItem';
import SearchRowSkeleton from '@components/Skeletons/SearchRowSkeleton';
import Text from '@components/Text';
import TextLink from '@components/TextLink';
import useEnvironment from '@hooks/useEnvironment';
import useLocalize from '@hooks/useLocalize';
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import interceptAnonymousUser from '@libs/interceptAnonymousUser';
import * as ReportUtils from '@libs/ReportUtils';
import {getNavatticURL} from '@libs/TourUtils';
import * as TripsResevationUtils from '@libs/TripReservationUtils';
import variables from '@styles/variables';
import * as IOU from '@userActions/IOU';
Expand Down Expand Up @@ -93,7 +95,8 @@ function EmptySearchView({type}: EmptySearchViewProps) {
}, [styles, translate, ctaErrorMessage]);

const [onboardingPurpose] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, {selector: (introSelected) => introSelected?.choice});
const navatticLink = onboardingPurpose === CONST.SELECTABLE_ONBOARDING_CHOICES.MANAGE_TEAM ? CONST.NAVATTIC.ADMIN_TOUR : CONST.NAVATTIC.EMPLOYEE_TOUR;
const {environment} = useEnvironment();
const navatticURL = getNavatticURL(environment, onboardingPurpose);

const content = useMemo(() => {
switch (type) {
Expand All @@ -120,7 +123,7 @@ function EmptySearchView({type}: EmptySearchViewProps) {
title: translate('search.searchResults.emptyExpenseResults.title'),
subtitle: translate('search.searchResults.emptyExpenseResults.subtitle'),
buttons: [
{buttonText: translate('emptySearchView.takeATour'), buttonAction: () => Link.openExternalLink(navatticLink)},
{buttonText: translate('emptySearchView.takeATour'), buttonAction: () => Link.openExternalLink(navatticURL)},
{
buttonText: translate('iou.createExpense'),
buttonAction: () => interceptAnonymousUser(() => IOU.startMoneyRequest(CONST.IOU.TYPE.CREATE, ReportUtils.generateReportID())),
Expand All @@ -140,7 +143,7 @@ function EmptySearchView({type}: EmptySearchViewProps) {
headerContentStyles: styles.emptyStateFolderWebStyles,
};
}
}, [type, StyleUtils, translate, theme, styles, subtitleComponent, ctaErrorMessage, navatticLink]);
}, [type, StyleUtils, translate, theme, styles, subtitleComponent, ctaErrorMessage, navatticURL]);

return (
<EmptyStateComponent
Expand Down
Loading

0 comments on commit 09032ea

Please sign in to comment.