Skip to content
Merged
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
6 changes: 0 additions & 6 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1103,7 +1103,6 @@ const CONST = {
PLAN_TYPES_AND_PRICING_HELP_URL: 'https://help.expensify.com/articles/new-expensify/billing-and-subscriptions/Plan-types-and-pricing',
MERGE_ACCOUNT_HELP_URL: 'https://help.expensify.com/articles/new-expensify/settings/Merge-Accounts',
CONNECT_A_BUSINESS_BANK_ACCOUNT_HELP_URL: 'https://help.expensify.com/articles/new-expensify/expenses-&-payments/Connect-a-Business-Bank-Account',
REGISTER_FOR_WEBINAR_URL: 'https://events.zoom.us/eo/Aif1I8qCi1GZ7KnLnd1vwGPmeukSRoPjFpyFAZ2udQWn0-B86e1Z~AggLXsr32QYFjq8BlYLZ5I06Dg',
TEST_RECEIPT_URL: `${CLOUDFRONT_URL}/images/fake-receipt__tacotodds.png`,
// Use Environment.getEnvironmentURL to get the complete URL with port number
DEV_NEW_EXPENSIFY_URL: 'https://dev.new.expensify.com:',
Expand Down Expand Up @@ -7068,11 +7067,6 @@ const CONST = {
EMBEDDED_DEMO_WHITELIST: ['http://', 'https://', 'about:'] as string[],
EMBEDDED_DEMO_IFRAME_TITLE: 'Test Drive',
},

ONBOARDING_HELP: {
TALK_TO_SALES: 'talkToSales',
REGISTER_FOR_WEBINAR: 'registerForWebinar',
},
} as const;

type Country = keyof typeof CONST.ALL_COUNTRIES;
Expand Down
3 changes: 0 additions & 3 deletions src/components/ButtonWithDropdownMenu/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ type WorkspaceTaxRatesBulkActionType = DeepValueOf<typeof CONST.POLICY.BULK_ACTI

type ReportExportType = DeepValueOf<typeof CONST.REPORT.EXPORT_OPTIONS>;

type OnboardingHelpType = DeepValueOf<typeof CONST.ONBOARDING_HELP>;

type DropdownOption<TValueType> = {
value: TValueType;
text: string;
Expand Down Expand Up @@ -137,5 +135,4 @@ export type {
ButtonWithDropdownMenuProps,
WorkspaceTaxRatesBulkActionType,
ReportExportType,
OnboardingHelpType,
};
88 changes: 0 additions & 88 deletions src/components/OnboardingHelpDropdownButton.tsx

This file was deleted.

2 changes: 0 additions & 2 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5022,8 +5022,6 @@ const translations = {
scheduleACall: 'Schedule call',
questionMarkButtonTooltip: 'Get assistance from our team',
exploreHelpDocs: 'Explore help docs',
registerForWebinar: 'Register for webinar',
onboardingHelp: 'Onboarding help',
},
emojiPicker: {
skinTonePickerLabel: 'Change default skin tone',
Expand Down
2 changes: 0 additions & 2 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5075,8 +5075,6 @@ const translations = {
scheduleACall: 'Programar llamada',
questionMarkButtonTooltip: 'Obtén ayuda de nuestro equipo',
exploreHelpDocs: 'Explorar la documentación de ayuda',
registerForWebinar: 'Registrarse para el seminario web',
onboardingHelp: 'Ayuda de incorporación',
},
emojiPicker: {
skinTonePickerLabel: 'Elige el tono de piel por defecto',
Expand Down
43 changes: 16 additions & 27 deletions src/pages/home/HeaderView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {BackArrow, CalendarSolid, DotIndicator, FallbackAvatar} from '@component
import LoadingBar from '@components/LoadingBar';
import MultipleAvatars from '@components/MultipleAvatars';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
import OnboardingHelpDropdownButton from '@components/OnboardingHelpDropdownButton';
import ParentNavigationSubtitle from '@components/ParentNavigationSubtitle';
import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback';
import ReportHeaderSkeletonView from '@components/ReportHeaderSkeletonView';
Expand All @@ -33,7 +32,6 @@ import useThemeStyles from '@hooks/useThemeStyles';
import {openExternalLink} from '@libs/actions/Link';
import {clearBookingDraft} from '@libs/actions/ScheduleCall';
import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID';
import getPlatform from '@libs/getPlatform';
import Navigation from '@libs/Navigation/Navigation';
import {getPersonalDetailsForAccountIDs} from '@libs/OptionsListUtils';
import Parser from '@libs/Parser';
Expand Down Expand Up @@ -79,6 +77,7 @@ import SCREENS from '@src/SCREENS';
import type {Report, ReportAction} from '@src/types/onyx';
import type {Icon as IconType} from '@src/types/onyx/OnyxCommon';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import TalkToSalesButton from './TalkToSalesButton';

type HeaderViewProps = {
/** Toggles the navigationMenu open and closed */
Expand Down Expand Up @@ -127,10 +126,9 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
const styles = useThemeStyles();
const isSelfDM = isSelfDMReportUtils(report);
const isGroupChat = isGroupChatReportUtils(report) || isDeprecatedGroupDM(report);
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, {canBeMissing: true});
const {canUseTalkToAISales} = usePermissions();
const isNativePlatform = getPlatform() === CONST.PLATFORM.IOS || getPlatform() === CONST.PLATFORM.ANDROID;
const shouldShowTalkToSales = !!canUseTalkToAISales && isAdminRoom(report) && !isNativePlatform;
const shouldShowTalkToSales = !!canUseTalkToAISales && isAdminRoom(report);

const allParticipants = getParticipantsAccountIDsForDisplay(report, false, true, undefined, reportMetadata);
const shouldAddEllipsis = allParticipants?.length > CONST.DISPLAY_PARTICIPANTS_LIMIT;
const participants = allParticipants.slice(0, CONST.DISPLAY_PARTICIPANTS_LIMIT);
Expand Down Expand Up @@ -216,8 +214,6 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
const shouldDisplaySearchRouter = !isReportInRHP || isSmallScreenWidth;
const [onboardingPurposeSelected] = useOnyx(ONYXKEYS.ONBOARDING_PURPOSE_SELECTED, {canBeMissing: true});
const isChatUsedForOnboarding = isChatUsedForOnboardingReportUtils(report, onboardingPurposeSelected);
const shouldShowRegisterForWebinar = introSelected?.companySize === CONST.ONBOARDING_COMPANY_SIZE.MICRO && isChatUsedForOnboarding;
const shouldShowOnBoardingHelpDropdownButton = shouldShowTalkToSales || shouldShowRegisterForWebinar;
const shouldShowEarlyDiscountBanner = shouldShowDiscount && isChatUsedForOnboarding;
const shouldShowGuideBookingButtonInEarlyDiscountBanner = shouldShowGuideBooking && shouldShowEarlyDiscountBanner && !isDismissedDiscountBanner;

Expand Down Expand Up @@ -246,12 +242,10 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
/>
);

const onboardingHelpDropdownButton = (
<OnboardingHelpDropdownButton
const talkToSalesButton = (
<TalkToSalesButton
reportID={report?.reportID}
shouldUseNarrowLayout={shouldUseNarrowLayout}
shouldShowTalkToSales={shouldShowTalkToSales}
shouldShowRegisterForWebinar={shouldShowRegisterForWebinar}
/>
);

Expand Down Expand Up @@ -376,7 +370,7 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
)}
</PressableWithoutFeedback>
<View style={[styles.reportOptions, styles.flexRow, styles.alignItemsCenter, styles.gap2]}>
{shouldShowOnBoardingHelpDropdownButton && !shouldUseNarrowLayout && onboardingHelpDropdownButton}
{!shouldShowEarlyDiscountBanner && shouldShowTalkToSales && !shouldUseNarrowLayout && talkToSalesButton}
{!shouldShowGuideBookingButtonInEarlyDiscountBanner && shouldShowGuideBooking && !shouldUseNarrowLayout && guideBookingButton}
{!shouldUseNarrowLayout && !shouldShowDiscount && isChatUsedForOnboarding && (
<FreeTrial
Expand Down Expand Up @@ -409,23 +403,18 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
</View>
{!isParentReportLoading && !isLoading && canJoin && shouldUseNarrowLayout && <View style={[styles.ph5, styles.pb2]}>{joinButton}</View>}
<View style={isChatUsedForOnboarding && !shouldShowDiscount && shouldShowGuideBooking && [styles.dFlex, styles.flexRow]}>
<View style={shouldShowOnBoardingHelpDropdownButton && [styles.flexRow, styles.alignItemsCenter, styles.gap1, styles.ph5]}>
{!shouldShowEarlyDiscountBanner && shouldShowOnBoardingHelpDropdownButton && shouldUseNarrowLayout && (
<View style={[styles.flex1, styles.pb3]}>{onboardingHelpDropdownButton}</View>
)}
{!isLoading && !shouldShowDiscount && isChatUsedForOnboarding && shouldUseNarrowLayout && (
<FreeTrial
pressable
addSpacing
success={!shouldShowGuideBooking}
inARow={shouldShowGuideBooking || shouldShowOnBoardingHelpDropdownButton}
/>
)}
</View>

{!shouldShowEarlyDiscountBanner && shouldShowTalkToSales && shouldUseNarrowLayout && <View style={getActionButtonStyles()}>{talkToSalesButton}</View>}
{!shouldShowGuideBookingButtonInEarlyDiscountBanner && !isLoading && shouldShowGuideBooking && shouldUseNarrowLayout && (
<View style={getActionButtonStyles()}>{guideBookingButton}</View>
)}
{!isLoading && !shouldShowDiscount && isChatUsedForOnboarding && shouldUseNarrowLayout && (
<FreeTrial
pressable
addSpacing
success={!shouldShowGuideBooking}
inARow={shouldShowGuideBooking}
/>
)}
</View>
{!!report && shouldUseNarrowLayout && isOpenTaskReport(report, parentReportAction) && (
<View style={[styles.appBG, styles.pl0]}>
Expand All @@ -438,7 +427,7 @@ function HeaderView({report, parentReportAction, onNavigationMenuButtonClicked,
</View>
{shouldShowEarlyDiscountBanner && (
<EarlyDiscountBanner
onboardingHelpDropdownButton={shouldUseNarrowLayout ? onboardingHelpDropdownButton : undefined}
TalkToSalesButton={shouldShowTalkToSales ? talkToSalesButton : undefined}
GuideBookingButton={shouldShowGuideBookingButtonInEarlyDiscountBanner ? guideBookingButton : undefined}
isSubscriptionPage={false}
onDismissedDiscountBanner={() => setIsDismissedDiscountBanner(true)}
Expand Down
5 changes: 5 additions & 0 deletions src/pages/home/TalkToSalesButton/index.native.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function TalkToSalesButton() {
return null;
}

export default TalkToSalesButton;
68 changes: 68 additions & 0 deletions src/pages/home/TalkToSalesButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import {useOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import {Close, Phone} from '@components/Icon/Expensicons';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import {initializeOpenAIRealtime, stopConnection} from '@libs/actions/OpenAI';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';

type TalkToSalesButtonProps = {
reportID: string | undefined;
shouldUseNarrowLayout: boolean;
};

function TalkToSalesButton({shouldUseNarrowLayout, reportID}: TalkToSalesButtonProps) {
const {translate} = useLocalize();
const [talkToAISales] = useOnyx(ONYXKEYS.TALK_TO_AI_SALES, {canBeMissing: false});
const styles = useThemeStyles();
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, {canBeMissing: true});
const [accountID] = useOnyx(ONYXKEYS.SESSION, {selector: (session) => session?.accountID, canBeMissing: false});

if (!reportID || !accountID) {
return;
}

// Only show for micro companies (1-10 employees)
if (introSelected?.companySize !== CONST.ONBOARDING_COMPANY_SIZE.MICRO) {
return null;
}

const abTestCtaText = (): string => {
const availableCTAs = [translate('aiSales.getHelp'), translate('aiSales.talkToSales'), translate('aiSales.talkToConcierge')];
return availableCTAs.at(accountID % availableCTAs.length) ?? translate('aiSales.talkToSales');
};

const talkToSalesIcon = () => {
if (talkToAISales?.isLoading) {
return undefined;
}
if (talkToAISales?.isTalkingToAISales) {
return Close;
}
return Phone;
};

return (
<Button
text={talkToAISales?.isTalkingToAISales ? translate('aiSales.hangUp') : abTestCtaText()}
onPress={() => {
if (talkToAISales?.isTalkingToAISales) {
stopConnection();
return;
}

initializeOpenAIRealtime(Number(reportID) ?? CONST.DEFAULT_NUMBER_ID, abTestCtaText());
}}
style={shouldUseNarrowLayout && styles.earlyDiscountButton}
icon={talkToSalesIcon()}
// Ensure that a button with an icon displays an ellipsis when its content overflows https://github.com/Expensify/App/issues/58974#issuecomment-2794297554
iconWrapperStyles={[styles.mw100]}
isContentCentered
isLoading={talkToAISales?.isLoading}
/>
);
}

export default TalkToSalesButton;
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ type EarlyDiscountBannerProps = {
GuideBookingButton?: React.JSX.Element;

/** The talk to sales button to display */
onboardingHelpDropdownButton?: React.JSX.Element;
TalkToSalesButton?: React.JSX.Element;

/** Function to trigger when the discount banner is dismissed */
onDismissedDiscountBanner?: () => void;
};

function EarlyDiscountBanner({isSubscriptionPage, GuideBookingButton, onboardingHelpDropdownButton, onDismissedDiscountBanner}: EarlyDiscountBannerProps) {
function EarlyDiscountBanner({isSubscriptionPage, GuideBookingButton, TalkToSalesButton, onDismissedDiscountBanner}: EarlyDiscountBannerProps) {
const theme = useTheme();
const styles = useThemeStyles();
const StyleUtils = useStyleUtils();
Expand Down Expand Up @@ -82,7 +82,7 @@ function EarlyDiscountBanner({isSubscriptionPage, GuideBookingButton, onboarding
const smallScreenStyle = shouldUseNarrowLayout ? [styles.flex0, styles.flexBasis100, styles.justifyContentCenter] : [];
return (
<View style={[styles.flexRow, styles.gap2, smallScreenStyle, styles.alignItemsCenter]}>
<View style={[shouldUseNarrowLayout && styles.w50]}>{onboardingHelpDropdownButton}</View>
{TalkToSalesButton}
{GuideBookingButton}
<Button
success
Expand All @@ -103,8 +103,7 @@ function EarlyDiscountBanner({isSubscriptionPage, GuideBookingButton, onboarding
styles.alignItemsCenter,
styles.earlyDiscountButton,
styles.mr2,
styles.w50,
onboardingHelpDropdownButton,
TalkToSalesButton,
GuideBookingButton,
translate,
dismissButton,
Expand Down
11 changes: 5 additions & 6 deletions src/pages/settings/Subscription/FreeTrial.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ type FreeTrialProps = {

function FreeTrial({badgeStyles, pressable = false, addSpacing = false, success = true, inARow = false}: FreeTrialProps) {
const styles = useThemeStyles();
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {canBeMissing: true});
const [firstDayFreeTrial] = useOnyx(ONYXKEYS.NVP_FIRST_DAY_FREE_TRIAL, {canBeMissing: true});
const [lastDayFreeTrial] = useOnyx(ONYXKEYS.NVP_LAST_DAY_FREE_TRIAL, {canBeMissing: true});
const [privateSubscription] = useOnyx(ONYXKEYS.NVP_PRIVATE_SUBSCRIPTION, {canBeMissing: true});
const [policies] = useOnyx(ONYXKEYS.COLLECTION.POLICY);
const [firstDayFreeTrial] = useOnyx(ONYXKEYS.NVP_FIRST_DAY_FREE_TRIAL);
const [lastDayFreeTrial] = useOnyx(ONYXKEYS.NVP_LAST_DAY_FREE_TRIAL);
const [privateSubscription] = useOnyx(ONYXKEYS.NVP_PRIVATE_SUBSCRIPTION);

const [freeTrialText, setFreeTrialText] = useState<string | undefined>(undefined);
const {isOffline} = useNetwork();
Expand All @@ -46,7 +46,6 @@ function FreeTrial({badgeStyles, pressable = false, addSpacing = false, success
icon={Star}
success={success}
text={freeTrialText}
iconWrapperStyles={[styles.mw100]}
onPress={() => Navigation.navigate(ROUTES.SETTINGS_SUBSCRIPTION.getRoute(Navigation.getActiveRoute()))}
/>
) : (
Expand All @@ -57,7 +56,7 @@ function FreeTrial({badgeStyles, pressable = false, addSpacing = false, success
/>
);

return addSpacing ? <View style={inARow ? [styles.pb3, styles.w50, styles.pl1] : [styles.pb3, styles.ph5]}>{freeTrial}</View> : freeTrial;
return addSpacing ? <View style={inARow ? [styles.pb3, styles.pr5, styles.w50, styles.pl1] : [styles.pb3, styles.ph5]}>{freeTrial}</View> : freeTrial;
}

FreeTrial.displayName = 'FreeTrial';
Expand Down
Loading