diff --git a/src/components/AddPaymentMethodMenu.tsx b/src/components/AddPaymentMethodMenu.tsx index 0057438e3913..50020906075d 100644 --- a/src/components/AddPaymentMethodMenu.tsx +++ b/src/components/AddPaymentMethodMenu.tsx @@ -117,7 +117,6 @@ function AddPaymentMethodMenu({ text: translate('common.businessBankAccount'), icon: Expensicons.Building, onSelected: () => { - completePaymentOnboarding(CONST.PAYMENT_SELECTED.BBA); onItemSelected(CONST.PAYMENT_METHODS.BUSINESS_BANK_ACCOUNT); }, }, diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index b846449faafd..7526720bddc0 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -5,6 +5,7 @@ import type {EmitterSubscription, GestureResponderEvent, View} from 'react-nativ import {useOnyx} from 'react-native-onyx'; import AddPaymentMethodMenu from '@components/AddPaymentMethodMenu'; import * as BankAccounts from '@libs/actions/BankAccounts'; +import {completePaymentOnboarding} from '@libs/actions/IOU'; import getClickedTargetLocation from '@libs/getClickedTargetLocation'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; @@ -108,7 +109,8 @@ function KYCWall({ Navigation.navigate(addDebitCardRoute); } else if (paymentMethod === CONST.PAYMENT_METHODS.BUSINESS_BANK_ACCOUNT) { if (iouReport && ReportUtils.isIOUReport(iouReport)) { - const {policyID, workspaceChatReportID, reportPreviewReportActionID} = Policy.createWorkspaceFromIOUPayment(iouReport) ?? {}; + const {policyID, workspaceChatReportID, reportPreviewReportActionID, adminsChatReportID} = Policy.createWorkspaceFromIOUPayment(iouReport) ?? {}; + completePaymentOnboarding(CONST.PAYMENT_SELECTED.BBA, adminsChatReportID, policyID); if (workspaceChatReportID) { Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(workspaceChatReportID, reportPreviewReportActionID)); } diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 4592500e9250..bdf760728576 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -1108,6 +1108,14 @@ function isPolicyAccessible(policy: OnyxEntry): boolean { return !isEmptyObject(policy) && (Object.keys(policy).length !== 1 || isEmptyObject(policy.errors)) && !!policy?.id; } +function areAllGroupPoliciesExpenseChatDisabled(policies = allPolicies) { + const groupPolicies = Object.values(policies ?? {}).filter((policy) => isPaidGroupPolicy(policy)); + if (groupPolicies.length === 0) { + return false; + } + return !groupPolicies.some((policy) => !!policy?.isPolicyExpenseChatEnabled); +} + export { canEditTaxRate, extractPolicyIDFromPath, @@ -1228,6 +1236,7 @@ export { getAllPoliciesLength, getActivePolicy, isPolicyAccessible, + areAllGroupPoliciesExpenseChatDisabled, }; export type {MemberEmailsToAccountIDs}; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 192f4fa3dbf8..5b3592407f89 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -7364,7 +7364,7 @@ function cancelPayment(expenseReport: OnyxEntry, chatReport: O * * @param paymentSelected based on which we choose the onboarding choice and concierge message */ -function completePaymentOnboarding(paymentSelected: ValueOf) { +function completePaymentOnboarding(paymentSelected: ValueOf, adminsChatReportID?: string, onboardingPolicyID?: string) { const isInviteOnboardingComplete = introSelected?.isInviteOnboardingComplete ?? false; if (isInviteOnboardingComplete || !introSelected?.choice || !introSelected?.inviteType) { @@ -7390,15 +7390,14 @@ function completePaymentOnboarding(paymentSelected: ValueOf, full = true) { if (chatReport.policyID && SubscriptionUtils.shouldRestrictUserBillableActions(chatReport.policyID)) { Navigation.navigate(ROUTES.RESTRICTED_ACTION.getRoute(chatReport.policyID)); diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index f514a9b27158..628e0918aa54 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -130,6 +130,7 @@ type WorkspaceFromIOUCreationData = { policyID: string; workspaceChatReportID: string; reportPreviewReportActionID?: string; + adminsChatReportID: string; }; const allPolicies: OnyxCollection = {}; @@ -2563,7 +2564,7 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): WorkspaceF API.write(WRITE_COMMANDS.CREATE_WORKSPACE_FROM_IOU_PAYMENT, params, {optimisticData, successData, failureData}); - return {policyID, workspaceChatReportID: memberData.workspaceChatReportID, reportPreviewReportActionID: reportPreview?.reportActionID}; + return {policyID, workspaceChatReportID: memberData.workspaceChatReportID, reportPreviewReportActionID: reportPreview?.reportActionID, adminsChatReportID}; } function enablePolicyConnections(policyID: string, enabled: boolean) { diff --git a/src/pages/Search/EmptySearchView.tsx b/src/pages/Search/EmptySearchView.tsx index 19d00a06771e..c26e8aeeb155 100644 --- a/src/pages/Search/EmptySearchView.tsx +++ b/src/pages/Search/EmptySearchView.tsx @@ -1,6 +1,8 @@ import React, {useMemo, useState} from 'react'; import {Linking, View} from 'react-native'; import {useOnyx} from 'react-native-onyx'; +import type {OnyxCollection} from 'react-native-onyx'; +import ConfirmModal from '@components/ConfirmModal'; import DotIndicatorMessage from '@components/DotIndicatorMessage'; import EmptyStateComponent from '@components/EmptyStateComponent'; import type {FeatureListItem} from '@components/FeatureList'; @@ -16,6 +18,7 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import interceptAnonymousUser from '@libs/interceptAnonymousUser'; +import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import {getNavatticURL} from '@libs/TourUtils'; import * as TripsResevationUtils from '@libs/TripReservationUtils'; @@ -24,6 +27,7 @@ import * as IOU from '@userActions/IOU'; import * as Link from '@userActions/Link'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import type * as OnyxTypes from '@src/types/onyx'; import type {SearchDataTypes} from '@src/types/onyx/SearchResults'; type EmptySearchViewProps = { @@ -46,6 +50,11 @@ function EmptySearchView({type}: EmptySearchViewProps) { const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); const styles = useThemeStyles(); + const [modalVisible, setModalVisible] = useState(false); + const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY); + const shouldRedirectToExpensifyClassic = useMemo(() => { + return PolicyUtils.areAllGroupPoliciesExpenseChatDisabled((allPolicies as OnyxCollection) ?? {}); + }, [allPolicies]); const [ctaErrorMessage, setCtaErrorMessage] = useState(''); @@ -126,7 +135,14 @@ function EmptySearchView({type}: EmptySearchViewProps) { {buttonText: translate('emptySearchView.takeATour'), buttonAction: () => Link.openExternalLink(navatticURL)}, { buttonText: translate('iou.createExpense'), - buttonAction: () => interceptAnonymousUser(() => IOU.startMoneyRequest(CONST.IOU.TYPE.CREATE, ReportUtils.generateReportID())), + buttonAction: () => + interceptAnonymousUser(() => { + if (shouldRedirectToExpensifyClassic) { + setModalVisible(true); + return; + } + IOU.startMoneyRequest(CONST.IOU.TYPE.CREATE, ReportUtils.generateReportID()); + }), success: true, }, ], @@ -143,21 +159,47 @@ function EmptySearchView({type}: EmptySearchViewProps) { headerContentStyles: styles.emptyStateFolderWebStyles, }; } - }, [type, StyleUtils, translate, theme, styles, subtitleComponent, ctaErrorMessage, navatticURL]); + }, [ + type, + StyleUtils, + theme.travelBG, + theme.emptyFolderBG, + translate, + styles.textAlignLeft, + styles.emptyStateFolderWebStyles, + subtitleComponent, + ctaErrorMessage, + navatticURL, + shouldRedirectToExpensifyClassic, + ]); return ( - + <> + + { + setModalVisible(false); + Link.openOldDotLink(CONST.OLDDOT_URLS.INBOX); + }} + onCancel={() => setModalVisible(false)} + title={translate('sidebarScreen.redirectToExpensifyClassicModal.title')} + confirmText={translate('exitSurvey.goToExpensifyClassic')} + cancelText={translate('common.cancel')} + /> + ); } diff --git a/src/pages/WorkspaceSwitcherPage/WorkspacesSectionHeader.tsx b/src/pages/WorkspaceSwitcherPage/WorkspacesSectionHeader.tsx deleted file mode 100644 index 89d052d263db..000000000000 --- a/src/pages/WorkspaceSwitcherPage/WorkspacesSectionHeader.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import React from 'react'; -import {View} from 'react-native'; -import Icon from '@components/Icon'; -import * as Expensicons from '@components/Icon/Expensicons'; -import {PressableWithFeedback} from '@components/Pressable'; -import Text from '@components/Text'; -import Tooltip from '@components/Tooltip'; -import useLocalize from '@hooks/useLocalize'; -import useTheme from '@hooks/useTheme'; -import useThemeStyles from '@hooks/useThemeStyles'; -import interceptAnonymousUser from '@libs/interceptAnonymousUser'; -import Navigation from '@libs/Navigation/Navigation'; -import * as App from '@userActions/App'; -import CONST from '@src/CONST'; - -type WorkspacesSectionHeaderProps = { - /** Should show the create workspace icon */ - shouldShowCreateWorkspaceIcon: boolean; -}; - -function WorkspacesSectionHeader({shouldShowCreateWorkspaceIcon}: WorkspacesSectionHeaderProps) { - const theme = useTheme(); - const styles = useThemeStyles(); - const {translate} = useLocalize(); - - return ( - - - - {translate('common.workspaces')} - - - {shouldShowCreateWorkspaceIcon && ( - - { - const activeRoute = Navigation.getActiveRouteWithoutParams(); - interceptAnonymousUser(() => App.createWorkspaceWithPolicyDraftAndNavigateToIt('', '', false, false, activeRoute)); - }} - > - {({hovered}) => ( - - )} - - - )} - - ); -} - -export default WorkspacesSectionHeader; diff --git a/src/pages/WorkspaceSwitcherPage/index.tsx b/src/pages/WorkspaceSwitcherPage/index.tsx index e418c5d5df59..ae3ba05c39c6 100644 --- a/src/pages/WorkspaceSwitcherPage/index.tsx +++ b/src/pages/WorkspaceSwitcherPage/index.tsx @@ -24,7 +24,6 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import WorkspaceCardCreateAWorkspace from './WorkspaceCardCreateAWorkspace'; -import WorkspacesSectionHeader from './WorkspacesSectionHeader'; type WorkspaceListItem = { text: string; @@ -183,7 +182,14 @@ function WorkspaceSwitcherPage() { pressableStyle={styles.flexRow} shouldSyncFocus={false} /> - + + + {translate('common.workspaces')} + + ListItem={UserListItem} sections={sections} diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index 82985c38c2ae..93d582c391c5 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -191,11 +191,7 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl * 2. none of the group policies they are a member of have isPolicyExpenseChatEnabled=true */ const shouldRedirectToExpensifyClassic = useMemo(() => { - const groupPolicies = Object.values(allPolicies ?? {}).filter((policy) => ReportUtils.isGroupPolicy(policy?.type ?? '')); - if (groupPolicies.length === 0) { - return false; - } - return !groupPolicies.some((policy) => !!policy?.isPolicyExpenseChatEnabled); + return PolicyUtils.areAllGroupPoliciesExpenseChatDisabled((allPolicies as OnyxCollection) ?? {}); }, [allPolicies]); const shouldShowNewWorkspaceButton = Object.values(allPolicies ?? {}).every(