From 9d64d17aacf22127bc93d2508a7ef2e7a5a94455 Mon Sep 17 00:00:00 2001 From: Shubham Agrawal Date: Sat, 21 Mar 2026 17:47:26 +0530 Subject: [PATCH] Removed unused getHelp content and components --- src/CONST/index.ts | 23 - .../HelpComponents/HelpBulletList.tsx | 26 - .../SidePanel/HelpComponents/HelpContent.tsx | 152 -- .../HelpComponents/HelpDiagnosticData.tsx | 39 - .../HelpComponents/HelpExpandable.tsx | 41 - .../SidePanel/HelpComponents/HelpHeader.tsx | 83 - .../HelpComponents/HelpNumberedList.tsx | 25 - .../SidePanel/HelpContent/helpContentMap.tsx | 2070 ----------------- src/components/SidePanel/getHelpContent.tsx | 68 - src/libs/ReportUtils.ts | 33 - src/libs/TransactionUtils/index.ts | 21 - src/types/onyx/IOU.ts | 2 +- tests/unit/ReportUtilsTest.ts | 102 - 13 files changed, 1 insertion(+), 2684 deletions(-) delete mode 100644 src/components/SidePanel/HelpComponents/HelpBulletList.tsx delete mode 100644 src/components/SidePanel/HelpComponents/HelpContent.tsx delete mode 100644 src/components/SidePanel/HelpComponents/HelpDiagnosticData.tsx delete mode 100644 src/components/SidePanel/HelpComponents/HelpExpandable.tsx delete mode 100644 src/components/SidePanel/HelpComponents/HelpHeader.tsx delete mode 100644 src/components/SidePanel/HelpComponents/HelpNumberedList.tsx delete mode 100644 src/components/SidePanel/HelpContent/helpContentMap.tsx delete mode 100644 src/components/SidePanel/getHelpContent.tsx diff --git a/src/CONST/index.ts b/src/CONST/index.ts index 4d6252b177eb1..067e94b3a5937 100644 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -1555,16 +1555,6 @@ const CONST = { BILL: 'bill', }, CHAT_TYPE: chatTypes, - HELP_TYPE: { - ...chatTypes, - CHAT_CONCIERGE: 'concierge', - EXPENSE_REPORT: 'expenseReport', - EXPENSE: 'expense', - CHAT: 'chat', - IOU: 'iou', - TASK: 'task', - INVOICE: 'invoice', - }, WORKSPACE_CHAT_ROOMS: { ANNOUNCE: '#announce', ADMINS: '#admins', @@ -3223,19 +3213,6 @@ const CONST = { START: 'start', END: 'end', }, - EXPENSE_TYPE: { - DISTANCE: 'distance', - MANUAL: 'manual', - SCAN: 'scan', - PER_DIEM: 'per-diem', - EXPENSIFY_CARD: 'expensifyCard', - PENDING_EXPENSIFY_CARD: 'pendingExpensifyCard', - DISTANCE_MAP: 'distance-map', - DISTANCE_MANUAL: 'distance-manual', - DISTANCE_GPS: 'distance-gps', - DISTANCE_ODOMETER: 'distance-odometer', - TIME: 'time', - }, REPORT_ACTION_TYPE: { PAY: 'pay', diff --git a/src/components/SidePanel/HelpComponents/HelpBulletList.tsx b/src/components/SidePanel/HelpComponents/HelpBulletList.tsx deleted file mode 100644 index 63bde1a278a8c..0000000000000 --- a/src/components/SidePanel/HelpComponents/HelpBulletList.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import type {ReactNode} from 'react'; -import React from 'react'; -import {View} from 'react-native'; -import Text from '@components/Text'; -import type {ThemeStyles} from '@styles/index'; -import CONST from '@src/CONST'; - -type HelpBulletListProps = { - styles: ThemeStyles; - items: ReactNode[]; -}; - -function HelpBulletList({items, styles}: HelpBulletListProps) { - return items.map((item, index) => ( - - {CONST.DOT_SEPARATOR} - {item} - - )); -} - -export default HelpBulletList; diff --git a/src/components/SidePanel/HelpComponents/HelpContent.tsx b/src/components/SidePanel/HelpComponents/HelpContent.tsx deleted file mode 100644 index ca9273d91cd24..0000000000000 --- a/src/components/SidePanel/HelpComponents/HelpContent.tsx +++ /dev/null @@ -1,152 +0,0 @@ -import {findFocusedRoute} from '@react-navigation/native'; -import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react'; -import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import ActivityIndicator from '@components/ActivityIndicator'; -import ScrollView from '@components/ScrollView'; -import getHelpContent from '@components/SidePanel/getHelpContent'; -import useEnvironment from '@hooks/useEnvironment'; -import useLocalize from '@hooks/useLocalize'; -import useOnyx from '@hooks/useOnyx'; -import useResponsiveLayout from '@hooks/useResponsiveLayout'; -import useRootNavigationState from '@hooks/useRootNavigationState'; -import useThemeStyles from '@hooks/useThemeStyles'; -import getNonEmptyStringOnyxID from '@libs/getNonEmptyStringOnyxID'; -import {normalizedConfigs} from '@libs/Navigation/linkingConfig/config'; -import {getOneTransactionThreadReportAction, getOriginalMessage, isMoneyRequestAction} from '@libs/ReportActionsUtils'; -import {getHelpPaneReportType} from '@libs/ReportUtils'; -import type {SkeletonSpanReasonAttributes} from '@libs/telemetry/useSkeletonSpan'; -import {getExpenseType} from '@libs/TransactionUtils'; -import CONST from '@src/CONST'; -import ONYXKEYS from '@src/ONYXKEYS'; -import type {Screen} from '@src/SCREENS'; -import type {ReportAction, ReportActions} from '@src/types/onyx'; -import HelpHeader from './HelpHeader'; - -type HelpContentProps = { - closeSidePanel: (shouldUpdateNarrow?: boolean) => void; -}; - -function HelpContent({closeSidePanel}: HelpContentProps) { - const styles = useThemeStyles(); - const {translate} = useLocalize(); - const {isProduction} = useEnvironment(); - const {isExtraLargeScreenWidth} = useResponsiveLayout(); - const [expandedIndex, setExpandedIndex] = useState(0); - - const {params, routeName, currentState} = useRootNavigationState((rootState) => { - // Safe handling when navigation is not yet initialized - if (!rootState) { - return { - routeName: '' as Screen, - params: {} as Record, - currentState: undefined, - }; - } - - const focusedRoute = findFocusedRoute(rootState); - setExpandedIndex(0); - return { - routeName: (focusedRoute?.name ?? '') as Screen, - params: focusedRoute?.params as Record, - currentState: rootState, - }; - }); - - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${params?.reportID || String(CONST.DEFAULT_NUMBER_ID)}`); - const [conciergeReportID = ''] = useOnyx(ONYXKEYS.CONCIERGE_REPORT_ID); - const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.reportID}`); - const [chatReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`); - - const getParentIOUReportActionSelector = useCallback( - (actions: OnyxEntry): OnyxEntry> => { - return Object.values(actions ?? {}) - .filter((action) => action.reportActionID === report?.parentReportActionID) - .find(isMoneyRequestAction); - }, - [report?.parentReportActionID], - ); - - const [parentIOUReportAction] = useOnyx( - `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.parentReportID}`, - { - selector: getParentIOUReportActionSelector, - }, - [getParentIOUReportActionSelector], - ); - - const transactionID = useMemo(() => { - const transactionThreadReportAction = getOneTransactionThreadReportAction(report, chatReport, reportActions ?? []); - return getOriginalMessage(parentIOUReportAction ?? transactionThreadReportAction)?.IOUTransactionID; - }, [report, chatReport, reportActions, parentIOUReportAction]); - const [transaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION}${getNonEmptyStringOnyxID(transactionID)}`); - - const route = useMemo(() => { - const path = normalizedConfigs[routeName]?.path; - - if (!path) { - return ''; - } - - const cleanedPath = path.replaceAll('?', ''); - const expenseType = getExpenseType(transaction); - const reportType = getHelpPaneReportType(report, conciergeReportID); - - if (expenseType && reportType !== CONST.REPORT.HELP_TYPE.EXPENSE_REPORT) { - return cleanedPath.replaceAll(':reportID', `:${CONST.REPORT.HELP_TYPE.EXPENSE}/:${expenseType}`); - } - - if (reportType) { - return cleanedPath.replaceAll(':reportID', `:${reportType}`); - } - - return cleanedPath; - }, [routeName, transaction, report, conciergeReportID]); - - const wasPreviousNarrowScreen = useRef(!isExtraLargeScreenWidth); - useEffect(() => { - // Close the Side Panel when the screen size changes from large to small - if (!isExtraLargeScreenWidth && !wasPreviousNarrowScreen.current) { - closeSidePanel(true); - wasPreviousNarrowScreen.current = true; - } - - // Reset the trigger when the screen size changes back to large - if (isExtraLargeScreenWidth) { - wasPreviousNarrowScreen.current = false; - } - }, [isExtraLargeScreenWidth, closeSidePanel]); - - const helpLoadingReasonAttributes: SkeletonSpanReasonAttributes = { - context: 'HelpContent', - }; - - return ( - <> - closeSidePanel(false)} - onCloseButtonPress={() => closeSidePanel(false)} - shouldShowBackButton={!isExtraLargeScreenWidth} - shouldShowCloseButton={isExtraLargeScreenWidth} - /> - {currentState === undefined ? ( - - - - ) : ( - - {getHelpContent(styles, route, isProduction, expandedIndex, setExpandedIndex)} - - )} - - ); -} - -export default HelpContent; diff --git a/src/components/SidePanel/HelpComponents/HelpDiagnosticData.tsx b/src/components/SidePanel/HelpComponents/HelpDiagnosticData.tsx deleted file mode 100644 index 50b788c5ea892..0000000000000 --- a/src/components/SidePanel/HelpComponents/HelpDiagnosticData.tsx +++ /dev/null @@ -1,39 +0,0 @@ -import React from 'react'; -import type {ReactNode} from 'react'; -import {View} from 'react-native'; -import Text from '@components/Text'; -import type {ThemeStyles} from '@styles/index'; - -type HelpDiagnosticDataProps = { - /** The styles to apply to the diagnostic data */ - styles: ThemeStyles; - - /** The route that was attempted to be accessed */ - route: string; - - /** Whether the route is an exact match */ - isExactMatch?: boolean; - - /** Help content to display */ - children?: ReactNode; -}; - -function HelpDiagnosticData({styles, route, children, isExactMatch}: HelpDiagnosticDataProps) { - const diagnosticTitle = isExactMatch ? 'Help content found for route:' : 'Missing help content for route:'; - - return ( - <> - {!!children && ( - <> - {children} - - - )} - Diagnostic data (visible only on staging) - {diagnosticTitle} - {route} - - ); -} - -export default HelpDiagnosticData; diff --git a/src/components/SidePanel/HelpComponents/HelpExpandable.tsx b/src/components/SidePanel/HelpComponents/HelpExpandable.tsx deleted file mode 100644 index 6fef78a13ae12..0000000000000 --- a/src/components/SidePanel/HelpComponents/HelpExpandable.tsx +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import type {StyleProp, ViewStyle} from 'react-native'; -import {View} from 'react-native'; -import Text from '@components/Text'; -import type {ThemeStyles} from '@styles/index'; - -type HelpExpandableProps = { - /** The content to be displayed when expanded. */ - children: React.ReactNode; - - /** Whether the component is expanded or not. */ - isExpanded: boolean; - - /** Function to toggle the expanded state. */ - setIsExpanded: () => void; - - /** Optional additional styles for the container. */ - containerStyle?: StyleProp; - - /** Styles object containing theme styles. */ - styles: ThemeStyles; -}; - -function HelpExpandable({children, styles, containerStyle, isExpanded, setIsExpanded}: HelpExpandableProps) { - return ( - - {isExpanded ? ( - children - ) : ( - - Show more - - )} - - ); -} - -export default HelpExpandable; diff --git a/src/components/SidePanel/HelpComponents/HelpHeader.tsx b/src/components/SidePanel/HelpComponents/HelpHeader.tsx deleted file mode 100644 index d69ca9fd188eb..0000000000000 --- a/src/components/SidePanel/HelpComponents/HelpHeader.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import React from 'react'; -import {View} from 'react-native'; -import Header from '@components/Header'; -import Icon from '@components/Icon'; -import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; -import Tooltip from '@components/Tooltip'; -import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; -import useLocalize from '@hooks/useLocalize'; -import useTheme from '@hooks/useTheme'; -import useThemeStyles from '@hooks/useThemeStyles'; -import CONST from '@src/CONST'; - -type HelpHeaderProps = { - /** Title of the header */ - title: string; - - /** Function to call when back button is pressed */ - onBackButtonPress: () => void; - - /** Function to call when close button is pressed */ - onCloseButtonPress: () => void; - - /** Whether to show the back button */ - shouldShowBackButton?: boolean; - - /** Whether to show the close button */ - shouldShowCloseButton?: boolean; -}; - -function HelpHeader({title, onBackButtonPress, onCloseButtonPress, shouldShowBackButton = true, shouldShowCloseButton = false}: HelpHeaderProps) { - const icons = useMemoizedLazyExpensifyIcons(['BackArrow', 'Close'] as const); - const styles = useThemeStyles(); - const theme = useTheme(); - - const {translate} = useLocalize(); - - return ( - - - {shouldShowBackButton && ( - - - - - - )} - -
- - {shouldShowCloseButton && ( - - - - - - )} - - - ); -} - -export default HelpHeader; diff --git a/src/components/SidePanel/HelpComponents/HelpNumberedList.tsx b/src/components/SidePanel/HelpComponents/HelpNumberedList.tsx deleted file mode 100644 index ba6afab3d0b79..0000000000000 --- a/src/components/SidePanel/HelpComponents/HelpNumberedList.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import type {ReactNode} from 'react'; -import React from 'react'; -import {View} from 'react-native'; -import Text from '@components/Text'; -import type {ThemeStyles} from '@styles/index'; - -type HelpNumberedListProps = { - styles: ThemeStyles; - items: ReactNode[]; -}; - -function HelpNumberedList({items, styles}: HelpNumberedListProps) { - return items.map((item, index) => ( - - {`${index + 1}.`} - {item} - - )); -} - -export default HelpNumberedList; diff --git a/src/components/SidePanel/HelpContent/helpContentMap.tsx b/src/components/SidePanel/HelpContent/helpContentMap.tsx deleted file mode 100644 index 69a6c12bdbcb6..0000000000000 --- a/src/components/SidePanel/HelpContent/helpContentMap.tsx +++ /dev/null @@ -1,2070 +0,0 @@ -/* eslint-disable react/jsx-key */ -/* eslint-disable react/no-unescaped-entities */ -/* eslint-disable @typescript-eslint/naming-convention */ -import type {ReactNode} from 'react'; -import React from 'react'; -import {View} from 'react-native'; -import BulletList from '@components/SidePanel/HelpComponents/HelpBulletList'; -import NumberedList from '@components/SidePanel/HelpComponents/HelpNumberedList'; -import Text from '@components/Text'; -import TextLink from '@components/TextLink'; -import type {ThemeStyles} from '@styles/index'; - -type ContentComponent = (props: {styles: ThemeStyles}) => ReactNode; - -type HelpContent = { - /** The content to display for this route */ - content?: ContentComponent; - - /** Any children routes that this route has */ - children?: Record; - - /** Whether this route is an exact match or displays parent content */ - isExact?: boolean; -}; - -const helpContentMap: HelpContent = { - children: { - home: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Navigating Expensify - Get familiar with Expensify’s intuitive navigation system designed for easy access to all your tools. - Left-hand Navigation Bar - - The vertical left-hand bar is your main navigation hub: - - - Expensify logo - Click to return to your Inbox (homepage) - , - - Inbox - Your personalized dashboard with action items and reminders - , - - Reports - Access all your expense reports and filtering tools - , - - Workspaces - Manage company and personal workspace settings - , - - Account - Personal settings, profile, and preferences - , - - Global Create button - Quick access to create reports, expenses, invoices, and chats - , - ]} - /> - Inbox Overview - - Your Inbox serves as the homepage and shows: - - Smart reminders to submit, approve, or reconcile expenses, - Real-time updates on recent actions and flagged reports, - List of chats with other employees in your organization, - Personalized action items based on your role and activity, - ]} - /> - Chat Features - Every expense, report, or workspace has an associated chat for collaboration: - - Text messages with rich formatting support - , - - Images & Documents via copy/paste, drag/drop, or attach button - , - - Expenses to track and submit for reimbursement - , - - Tasks to assign and manage work items - , - - Mentions to invite anyone by email or phone number - , - ]} - /> - Reports Section - - The Reports tab consolidates filtering and reporting: - - - Use the Workspace filter inside the Filters menu to refine results - , - Apply filters and queries that update automatically, - View all expense reports across your workspaces, - ]} - /> - Quick Actions - - Use the green Create button to quickly: - - Start a new chat or conversation, - Create an expense report, - Add an expense or receipt, - Create a task or invoice, - Submit expenses for approval, - ]} - /> - - - Tip: Navigation is consistent across web and mobile versions of Expensify. - - - ), - }, - distance: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Distance Expense - - Easily track mileage costs using Expensify’s built-in map feature. Create and submit distance-based expenses right from the web or mobile app. - - - - Create distance expenses: Click the green + button and choose Create expense, then select Distance. Enter your - starting point and destination. You can also add stops if needed. - - , - - - Submit for approval: Choose your workspace and confirm the distance, amount, and date. Add optional notes or - categories, then click Create expense to submit the mileage expense for approval. - - , - - - Log a round-trip: To log a round-trip, use the same location for both start and finish, and include any stops along - the way. - - , - ]} - /> - - ), - }, - r: { - children: { - ':concierge': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Concierge - - Concierge is available 24/7 to answer any question you have about anything — whether that’s how to get set up, how to fix a problem, or general best - practices. Concierge is a bot, but it’s really smart and can escalate you to a human whenever you want. Say hi — it’s friendly! - - - ), - }, - ':expense': { - children: { - ':scan': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Scanned - A “scanned” expense was created by extracting the relevant details using the Concierge AI. - - ), - }, - ':manual': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Manual - - A “manual” expense has had all its details specified by the workspace member. It was not imported from any system, or scanned from a receipt. - - - ), - }, - ':pendingExpensifyCard': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Expensify Card (pending) - - A “pending” Expensify Card expense represents a purchase that was recently made on the card, but has not yet “posted” – meaning, it has not been - formally recognized as a final, complete transaction. - - Any changes made to this expense will be preserved when the expense posts, typically 2-7 days later. - Pending transactions cannot be approved, as the final expense amount will not be confirmed until it posts. - - ), - }, - ':expensifyCard': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Expensify Card - An “Expensify Card” expense corresponds to a “posted” (meaning, finalized by the bank) purchase. - - Expensify Card expenses cannot be reimbursed as they are centrally paid by the bank account linked to the workspace. - - - ), - }, - }, - content: ({styles}: {styles: ThemeStyles}) => ( - - Expense - Every expense gets a dedicated chat to discuss that specific expense. The expense consists of: - - Receipt – Attach a photo or document to this expense. - , - - Amount – The financial total of this transaction. - , - - Description – A general explanation of what this expense was for. - , - - Merchant – The business this purchase was made at. - , - - Date – The day on which the purchase was made. - , - ]} - /> - - The expense chat is shared with everyone in the approval flow, and will maintain an audit trail of all historical changes. - - - ), - }, - ':chat': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Chat - - Chat is the foundation of New Expensify. Every expense, expense report, workspace, or member has an associated “chat”, which you can use to record additional - details, or collaborate with others. Every chat has the following components: - - Header - - This shows who you are chatting with (or what you are chatting about). You can press the header for more details on the chat, or additional actions to take - upon it. - - Comments - The core of the chat are its comments, which come in many forms: - - Text – Rich text messages stored securely and delivered via web, app, email, or SMS. - , - - Images & Documents – Insert photos, screenshots, movies, PDFs, or more, using copy/paste, drag/drop, or the - attach button. - , - - Expenses – Share an expense in the chat, either to simply track and document it, or to submit for reimbursement. - , - - Tasks – Record a task, and optionally assign it to someone (or yourself!). - , - ]} - /> - Actions - Hover (or long press) on a comment to see additional options, including: - - React – Throw a ♥️😂🔥 like on anything! - , - - Reply in thread – Go deeper by creating a new chat on any comment. - , - - Mark unread – Flag it for reading later, at your convenience. - , - ]} - /> - Composer - Use the composer at the bottom to write new messages: - - Markdown – Format text using bold,{' '} - italics, and{' '} - - more - - . - , - - Mention – Invite or tag anyone in the world to any chat by putting an @ in front of their email address or phone - number (e.g., @awong@marslink.web, or @415-867-5309). - , - ]} - /> - - ), - }, - ':policyAdmins': { - content: ({styles}: {styles: ThemeStyles}) => ( - - #admins - - Every workspace automatically receives a special #admins chat room. Every admin is automatically added to this room as a member. The #admins room is used for - several purposes: - - - - Talking with Concierge, your setup specialist, or your account manager – When you first create the workspace, - Concierge and a setup specialist will be added. Feel free to ask any setup questions you have about how to configure the workspace, onboard your - team, connect your accounting, or anything else you might need. - - , - - - Monitoring workspace changes – Every #admins room shows an audit trail of any configuration changes or - significant events happening inside the workspace. - - , - - - Chatting with other admins – The #admins room is a useful space for workspace admins to chat with each other - about anything, whether or not it relates to Expensify. - - , - ]} - /> - - ), - }, - ':expenseReport': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Expense Report - Every expense report gets a dedicated chat to discuss expenses, approvals, or anything you like. The expense report chat: - Is shared with everyone in the approval flow configured inside the workspace., - Will maintain an audit trail of all historical workflow actions (i.e., approvals)., - ]} - /> - - Press the attach button to add more expenses, or press the header for more options. Press on any expense to go deeper. - - - ), - }, - ':policyExpenseChat': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Workspace - - Every workspace member gets a special chat between them and all workspace admins. This is a good place for workspace members to ask questions about expense - policy, for workspace admins to explain changes, or for any “formal” conversation to occur between members and admins. Press the attach button to: - - - Create expense – This will submit an expense to the workspace for reimbursement. - , - - Split expense – This will split an expense between the member and the workspace (e.g., for a business meal that - brings a spouse). - , - ]} - /> - All past expense reports are processed here and stored for historical reference. - - ), - }, - ':policyAnnounce': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Announce Room (#announce) - - The #announce room is a chat space available to all workspace members. It’s perfect for sharing company-wide updates, policy changes, or event reminders. The - #announce room is accessible from your Inbox in the left-hand menu. - - - - Post company-wide announcements: All members can post in #announce by default, making it easy to communicate - across the workspace. - - , - - - Restrict posting to admins: Workspace admins can limit posting to admins only. Open the #announce room, click - the room header, select Settings, and change Who can post to Admins only. - - , - - - Everyone can read messages: Even if posting is limited to admins, all workspace members can still view - messages in the #announce room. - - , - ]} - /> - - ), - }, - }, - content: ({styles}: {styles: ThemeStyles}) => ( - - Inbox - The Inbox is a prioritized “to do” list, highlighting exactly what you need to do next. It consists of: - Priorities - At the top of the Inbox are the most important tasks you should do first, which include: - Expense reports waiting on you, - Tasks assigned to you, - Chats that have mentioned you, - Anything you have pinned, - ]} - /> - Chats - Beneath the priorities are a list of chats (with unread chats highlighted in bold), in one of two view modes: - - Most Recent – Lists every chat, ordered by whichever was most recently active. - , - - Focus – Only lists chats with unread messages, sorted alphabetically. - , - ]} - /> - - ), - }, - scan: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Scan Receipt - SmartScan automatically extracts expense details from receipt images. - How to Scan - - Click the + button and select Create expense - , - - Choose Scan - , - Upload an image or take a photo of your receipt, - SmartScan extracts merchant, date, amount, and currency, - Choose your workspace and add any required details, - - Click Create expense - , - ]} - /> - What SmartScan Detects - - Amount and currency - , - - Merchant name and location - , - - Date of purchase - , - - Tax information (when visible) - , - - Category suggestions based on merchant type - , - ]} - /> - Supported Receipt Types - - Photos - Take with your device camera - , - - Email receipts - Forward to receipts@expensify.com - , - - PDF receipts - Upload from your device - , - - Screenshots - From apps or websites - , - ]} - /> - Tips for Best Results - Ensure receipt text is clear and readable, - Include the full receipt in the image, - Good lighting improves accuracy, - Straight angles work better than tilted photos, - ]} - /> - After Scanning - Review extracted details for accuracy, - Add description, category, or tags as needed, - SmartScan learns from your corrections, - ]} - /> - Related Links - - - Create an Expense - - , - - - Free Features in Expensify - - , - ]} - /> - - ), - }, - workspaces: { - children: { - ':policyID': { - children: { - accounting: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Accounting Integrations - - Link your workspace directly to your accounting system to make expense tracking smarter and smoother. We’ll automatically sync your chart of accounts - so your team can code expenses accurately — and approved reports flow right back into your books. Less manual work, more peace of mind. - - - Once connected, you can fine-tune your setup with: - - Import settings to control what data comes from your accounting system., - Export settings to choose how expense reports are sent back., - Advanced options for automation, such as auto-sync and employee settings., - ]} - /> - - Supported Integrations - - QuickBooks Online - - Real-time expense sync, - Category and vendor mapping, - Tax rate sync, - ]} - /> - - QuickBooks Desktop - - File-based import/export, - Chart of accounts sync, - Custom field mapping, - ]} - /> - - Xero - - Auto-sync approved reports, - Import tracking categories, - Manage tax rates seamlessly, - ]} - /> - - NetSuite - - Built for complex orgs with multi-entity support, - Custom dimension mapping, - Automated bill payments, - ]} - /> - - Sage Intacct - - Track departments, classes, and more, - Multi-currency support, - Advanced approval workflows, - ]} - /> - - What Syncs Automatically - - From your accounting system: - - Chart of accounts (as categories), - Classes, departments, locations (as tags), - Tax rates and customers, - Vendors and bill payment accounts, - ]} - /> - - To your accounting system: - - Approved expense reports, - Company card transactions, - Vendor bills and journal entries, - Payment records and reconciliation data, - ]} - /> - - Learn More - - - Connect to QuickBooks Online - - , - - - Connect to Xero - - , - - - Connect to NetSuite - - , - ]} - /> - - ), - }, - invoices: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Create and Send Invoices - - Send invoices, track their status, and get paid — even if your customer isn’t on Expensify. Invoicing comes included with all Expensify subscriptions. - - - - - Set Up Invoicing: Add a business bank account to start sending and receiving invoice payments. - - , - - - Invoice Balance: Right up top, you’ll see your current invoice balance — that’s the money you’ve - collected from paid invoices. If you’ve added a bank account, this balance will transfer automatically. - - , - - - Customize Your Invoices: Make your invoices your own. Add your company name, website, and logo — - they’ll show up on every invoice you send. - - , - ]} - /> - - ), - }, - 'distance-rates': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Distance Rates - - Distance rates make it easy to pay employees when they use their personal vehicles for work. You can set different rates for different vehicle types - or travel situations. Just make sure at least one rate is active when this feature is turned on. - - - - - How to set up rates: Under{' '} - Workspaces > [Workspace Name] > Distance rates and choose{' '} - Add rate. Enter how much you’ll reimburse per mile or kilometer and click{' '} - Save. - - , - - - Multiple rate options: Customize rates for personal cars, company vehicles, or different types of - trips. - - , - - - Managing your rates: To save time, you can turn rates on or off, update amounts, or manage them in - bulk. - - , - ]} - /> - - - You can learn more about managing distance rates here ➡️{' '} - - Set Distance Rates - - . - - - ), - }, - workflows: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Workflows - - Setting up workflows on your workspace automates how expenses move from submission to payment. They keep things organized and help you control when - expenses are submitted, who approves them, and how they get paid. - - - Note: Only admins can configure workspace workflows. - - - - - Approval setup: Assign approvers to review expenses before they’re paid. You can even customize - approvers for different team members. - - , - - - Submission timing: Pick a daily or weekly schedule for automatic expense submission so no one forgets - to submit their expenses. - - , - - - Automated payments: Link your business bank account, and Expensify will automatically process - payments for approved expenses and invoices. - - , - ]} - /> - - Learn More - - - Workspace Workflows - - , - - - Approval Settings - - , - ]} - /> - - ), - }, - 'expensify-card': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Expensify Card - - The Expensify Card is a smart company card with real-time controls and built-in cash back. It allows you to issue unlimited virtual cards, set custom - limits for each employee, and manage everything in one place. - - - Note: You’ll need a connected US business bank account to get started. - - - - - Issue cards: Hand out virtual or physical cards with flexible spending controls, such as smart - limits, monthly caps, or fixed amounts. - - , - - - Smarter spending controls: Set custom limits, block certain merchant types, and track every swipe in - real time. - - , - - - Easy card management: As a workspace admin, you can see all issued cards at a glance. You can adjust - limits, rename cards, or deactivate them whenever you need to. - - , - ]} - /> - - - More details on setting up the Expensify Card for your business can be found here ➡️{' '} - - The Expensify Card - - . - - - ), - }, - tags: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Tag Settings - - Tags help you track extra details on expenses—like projects, cost centers, locations, or clients—so you can organize your spend beyond just - categories. You can add them manually or sync them automatically from your accounting software. - - - - - How to add tags: Click the green + button to add tags manually, or upload up to 50,000 at once with a - spreadsheet. Using an accounting integration? Your tags will sync automatically. - - , - - - Organizing tags: Use dependent tags (where one relies on another) for more structured tracking, or - keep things simple with independent tags. - - , - - - Automatic tagging that gets smarter: Expensify learns how you tag expenses and starts doing it for - you, speeding up and simplifying your workflow over time. - - , - ]} - /> - - Learn More - - - Create Tags - - , - - - Require Tags for Expenses - - , - ]} - /> - - ), - }, - 'per-diem': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Per Diem Settings - - Per diem makes it easy to cover travel or recurring allowances with fixed daily rates—no need to track every coffee or cab ride. Employees just pick a - rate and submit. You can create rates manually or import them from a spreadsheet. - - - - - Set up rates: Create daily rates for different locations, meal types, or travel needs. Just enter the - amount, and you’re done! - - , - - - Default categories: Assign a default category to keep all your per diem expenses organized and your - accounting on track. - - , - ]} - /> - - - Learn more about setting up per diem rates here ➡️{' '} - - Per Diem Settings - - . - - - ), - }, - taxes: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Tax Settings - - Track VAT, GST, or any other regional taxes right in Expensify. Perfect for staying compliant—especially if you’re working in non-USD currencies. You - can set up different tax rates for your workspace currency and for foreign currencies, too. - - - - - How to set up tax rates: Click the green + button to add a tax rate. Just enter the tax name, - percentage, and tax code for your records. - - , - - - Default tax settings: Set separate default rates for your workspace currency and foreign currencies, - so everything’s accurate no matter where you’re spending. - - , - - - Managing tax rates: You can turn rates on or off, update their values, or delete them entirely. Use - bulk actions to move faster, or make changes one at a time. - - , - ]} - /> - - - Learn more about workspace tax settings here ➡️{' '} - - Track Taxes - - . - - - ), - }, - rules: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Workspace Rules - - Rules help you stick to your expense policy without micromanaging. Set limits, require receipts, and automate approvals. Expensify checks every - expense against your rules and flags anything that’s off. - - - Note: Workspace rules are only available on the Control plan. - - - - - Expense requirements: Decide when receipts are required, set a max spend per expense, and control how - far back expenses can be submitted. - - , - - - Prohibited expenses: Let Expensify’s AI catch restricted items like alcohol, gambling, or tobacco—no - manual review needed. - - , - - - Automatic approvals: Save time by auto-approving compliant reports under a certain amount. You can - even randomly audit a few to keep everyone honest. - - , - ]} - /> - - Learn More - - - Workspace Rules - - , - - - Prohibited Expense Rules - - , - ]} - /> - - ), - }, - members: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Workspace Members - - Invite teammates to your workspace and assign roles to control their access and keep the expense process running smoothly. - - - Member Roles - - Admin - - Full workspace control and settings access, - Add/remove members and change roles, - Set up integrations and payment methods, - Approve and pay expenses, - ]} - /> - - Member - - Submit expenses and create reports, - Participate in workspace chats, - View assigned expenses and reports, - ]} - /> - - Auditor - - View all workspace reports (read-only), - Add comments, but cannot modify expenses, - No approval or payment permissions, - ]} - /> - Adding Members - - Under Workspaces > [Workspace Name] > Members, click{' '} - Invite Member - , - Enter name, email, or phone number, - Choose a role (defaults to Member), - - Click Invite - , - ]} - /> - - Alternative: Share the workspace URL or QR code from{' '} - Account > Profile > Share - - Managing Members - - Change Role: - - Click the member’s name, - - Click Role and select new role - , - Confirm changes, - ]} - /> - - Remove Member: - - Click the member’s name, - - Click Remove from Workspace - , - Confirm removal, - ]} - /> - Transfer Ownership of a Workspace - - Go to Members and click current Owner - , - - Click Transfer Owner - , - Confirm transfer, - You become the new owner, - ]} - /> - Learn More - - - Managing Workspace Members - - , - - - Add Approvals - - , - ]} - /> - - ), - }, - 'company-cards': { - content: ({styles}: {styles: ThemeStyles}) => ( - - Company Cards - - Already have business credit cards? You can connect them to Expensify to automatically pull in transactions. Most major banks and card providers are - supported. - - - - - How to connect cards: Link your corporate card program to your workspace, assign the cards to the - corresponding cardholder, and transactions will start syncing automatically as they post—no manual entry needed. - - , - - - Exporting expenses: Send card transactions to your accounting system, either to a shared account or - separate ones for each cardholder. - - , - - - eReceipts: Turn on eReceipts to automatically generate digital receipts for USD transactions under - $75—no more chasing paper ones. - - , - ]} - /> - - - More details on connecting your company card program can be found here ➡️{' '} - - Company Card Settings - - . - - - ), - }, - reportFields: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Report Settings - Keep your reports clean, consistent, and easy to manage by customizing titles and adding report-level details. - - - - Report title: Use the Custom Report Names feature (under workspace Rules) to create naming templates - for new reports. It’s a smarter way to keep things organized and make reports easier to find. You also have the option to prevent members - from changing the custom report names you set. - - , - - - Report fields: Collect high-level info—like project names, client codes, or trip types—that applies - to the whole report, not just individual expenses. Report fields are filled out once and apply to all expenses in that report. - - , - ]} - /> - - Turn on and Manage Report Fields - - Note: This setting requires the Control plan. - - - Under Workspaces > More Features, toggle on Report fields - , - - Head to Workspaces > [Workspace Name] > Reports to add, edit, or delete fields - , - ]} - /> - - You can choose from field types like Text, Date, or a List with predefined options — whatever best fits your workflow. Learn more ➡️{' '} - - Enable Report Fields - - . - - - ), - }, - overview: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Workspace Overview - Set up the essentials — name, description, currency, address, and subscription plan — all in one spot. - - - - Choose your workspace currency: Pick a default currency. No matter what currency members use, we’ll - convert everything automatically. - - , - - - Add workspace details: Give your workspace a name, add a quick description, and drop in your company - address. These show up on reports and invoices, so make it yours. - - , - - - Manage your subscription: Your plan controls what features you get and how much you pay per active - user. Hit Explore all plans to switch things up or adjust your size. - - , - ]} - /> - - ), - }, - categories: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Category Settings - - Categories help you organize expenses so your reports and accounting stay clean and easy to manage. Think of them as your chart of accounts or GL - codes. You can add them manually or, if you use accounting software, import them straight from the integration. - - - - - Category settings made simple: You can toggle categories on or off, add GL codes, and set rules like - receipt requirements or spending limits, all in one place under{' '} - Workspaces > [Workspace Name] > Categories. - - , - - - Smarter categorization, automatically: Expensify learns how you tag your expenses and starts - automatically applying those categories to similar merchants. This means less busywork and more accuracy. - - , - ]} - /> - - Learn More - - - Create Expense Categories - - , - - - Require Categories - - , - ]} - /> - - ), - }, - }, - }, - }, - content: ({styles}: {styles: ThemeStyles}) => ( - - Workspaces 101 - - Think of a workspace as mission control for your company’s expenses. It’s where you set the rules, invite the team, and connect to your accounting tools. Each - workspace runs independently, so you can keep things tidy across departments, entities, or clients. - - Create a new workspace - - Hit the New workspace button to get started. Add a name, set a default currency, and you’re ready to get started customizing the - workspace settings! - - Invite your team - Add teammates to your workspace to manage expenses and approvals in one central place: - Members can submit and approve reports they’re assigned to., - Admins can approve all reports and manage workspace settings., - ]} - /> - Automate approvals - - Toggle on Add Approvals under Workflows to set a default first approver. Create custom - approval flows for individual team members if needed. - - Connect your accounting system - Link your workspace with QuickBooks Online, Xero, NetSuite, or Sage Intacct to sync expenses like a pro. - Enhance your workspace with extra features - - Under More Features, enable extras like the Expensify Card, distance rates, custom categories and tags, and company card - connections. - - - - Tip: If you manage multiple departments, clients, or entities, consider creating multiple workspaces. Separate workspaces can - help keep settings, approvals, and payments organized and more automated. - - - ), - }, - settings: { - children: { - preferences: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Preferences - - Your preferences shape how Expensify looks and feels just for you. Customize your language, theme, and notification settings to customize your experience - across all your devices. - - - - - Notifications: Decide which alerts you want to receive, such as feature updates, news, or sound - notifications. You’re in control. - - , - - - Priority mode: Choose how chats appear in your inbox – Focus on unread and pinned chats, or keep everything - visible, with the most recent messages shown at the top of the left-hand menu. - - , - - - Language options: You can update your interface in just a few clicks by choosing from 10 supported languages. - Choose your preferred language from the list, and your account will update automatically. - - , - - - Payment Currency: Set your default currency for expense tracking and reimbursements. - - , - <> - - Theme: Change the app’s appearance to suit your preference: - - - - Dark Mode - Easy on the eyes in low-light environments - , - - Light Mode - Bright, clean interface for well-lit spaces - , - - Use Device Settings - Automatically match your device’s theme - , - ]} - /> - , - ]} - /> - - - Note: Preference changes only affect your personal account view. Workspace members must update their own settings - individually. - - - ), - }, - security: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Security - - This is where you control who can access your account and how secure it is. From adding two-factor authentication to merging accounts, it’s all in one spot. - - - Two-Factor Authentication - - This adds an extra layer of protection to your Expensify account. Even if someone gets your login info, they won’t be able to access it without a code from - your authenticator app. - - - - Set it up in a minute: Use an app like Google Authenticator or Microsoft Authenticator to link your account. - - , - - - Don’t skip the backup codes: Download or save your recovery codes somewhere safe. You’ll need them if you - ever lose access to your app. - - , - - - How login works: You’ll log in with your email magic code and a 6-digit code from your authenticator app. - - , - ]} - /> - - Merge Accounts - - If you’ve ended up with two Expensify accounts, you can merge them to keep expense history and workspace access under a single login. - - - - Heads up: Merging is permanent and must be done from your company account by pulling in the personal one. - - , - - - How to merge: Under Account > Security > Merge accounts, add the - email address of the account you’re merging and then enter the magic code sent to your email. - - , - - - What moves over: Expenses, reports, cards, co-pilots — everything from the merged account rolls over into - your existing account. - - , - ]} - /> - - Report Suspicious Activity - - If something feels off or you’re concerned a bad actor has gained access to your account, report it by clicking{' '} - Report suspicious activity. This will fully lock down your account and halt Expensify Card transactions immediately. - - - Close Account - If you need to close your Expensify account, you can do that here — there are just a few things to check off first. - - - Before you close: Make sure to transfer ownerships, clear any balances, and update billing contacts. - - , - - - After closing the account: Shared reports and expenses will still be accessible to workspace admins, but all - your personal data will be wiped. - - , - ]} - /> - - Learn More - - - Two-Factor Authentication - - , - - - Report Suspicious Activity - - , - - - Merge Accounts - - , - - - Close Account - - , - ]} - /> - - ), - }, - subscription: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Subscription Plan - - Your subscription plan determines which features are available and how much you’re charged per active member. Choose the one that fits your team’s needs and - budget! - - - - - Expensify offers two plans – Collect and Control: The Collect plan is $5 per member each month. The Control - plan ranges from $9 to $36 per member/month, depending on your subscription commitment and how much your team uses the Expensify Card. - - , - - - Add a payment card: To pay for your subscription, add a payment card under{' '} - Account > Subscription. Charges will automatically be billed to this card each month. - - , - - - Change plan: You can switch plans by clicking Explore all plans. You can - upgrade your plan or increase your subscription size at any time. - - , - - - Request Tax-Exempt Status: Under{' '} - Account > Subscription > Subscription settings, click{' '} - Tax exempt status. This kicks off a chat with Concierge, where you can request that your account be - tax-exempt and then upload a PDF of your exemption document. Our team will review everything and reach out if we need anything else. - - , - ]} - /> - - Learn More - - - Billing Overview - - , - - - Change Workspace Plan - - , - - - Tax Exemption - - , - ]} - /> - - ), - }, - profile: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Profile - - Your profile is where you control how you show up in Expensify. Update your photo, name, status, and timezone so teammates know who they’re working with. - Private info like your legal name and address stays visible to you only. - - - - Setting your status: Add a custom status (yep, emojis included) to show if you’re in a meeting, out of - office, or just heads-down for a bit. - - , - - - Managing contact methods: Add backup emails or phone numbers to keep your account secure and accessible, even - if your primary email changes. - - , - ]} - /> - - ), - }, - wallet: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Wallet - - Your Wallet is the hub for all things money in Expensify. This is where you connect and manage your business and personal bank accounts, view company card - details, and control how money moves in and out of your organization. Whether you’re reimbursing employees, collecting payments, or issuing Expensify Cards, - it all starts here. - - - Business Bank Accounts - - Connect a verified business bank account to unlock smart features like reimbursements, bill pay, invoice collection, and the Expensify Card. - - - - Turn on payments: Head to{' '} - Workspaces > [Workspace Name] > More features, click{' '} - Enable workflows, then toggle on Make or track payments. From there, hit{' '} - Connect bank account to get started. - - , - - - Connect your account: Use Plaid to link your account in seconds, or enter your details manually. You’ll need - to upload an ID, add your company info, and verify the account with a few test transactions. - - , - <> - Once your account is verified, you can: - - Reimburse employees via ACH, - Pay vendors and suppliers, - Issue Expensify Cards to your team, - Collect invoice payments from clients, - ]} - /> - , - - Share access to the bank account with another admin: Under{' '} - Settings > Account > Wallet, click Share next to the bank account, and - enter the admin’s email. They’ll just need to revalidate the bank account on their end before they can issue payments. - , - ]} - /> - - Personal Bank Accounts - - If you want to get reimbursed or paid directly in Expensify, add a personal bank account — Expensify supports banks in over 190 countries. - - - - Add your bank account: Under Settings > Wallet > Bank accounts, - click Add bank account, choose your country, and connect via Plaid or enter your info manually. - - , - - - Note: Personal bank accounts are for receiving funds only. You’ll need a verified business bank account to - send payments or issue Expensify Cards. - - , - ]} - /> - - Assigned Cards - - Company cards are assigned at the workspace level, but are visible to the individual cardholder in their Wallet. The - cards sync automatically, so you can skip manually entering credit card expenses. - - - - See card details (Expensify Card): Click Reveal details to check your - card number, expiration date, and security code for online purchases. - - , - - - Track expenses smarter: Transactions pull in automatically and match with SmartScanned receipts to keep - records audit-ready. - - , - - - View transactions: Click on a connected card and then View transactions{' '} - to see all of the imported expenses from that company card. - - , - ]} - /> - - Learn More - - - Connect a Business Bank Account - - , - - - Connect a Personal Bank Account - - , - - - Expensify Cardholder Settings and Features - - , - ]} - /> - - ), - }, - }, - }, - new: { - children: { - task: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Tasks - - Keep conversations organized by letting you create actionable to-dos directly within a chat. You can assign them to yourself or others in both 1:1 and group - chats. - - - - Create a task: In any chat, click the + button next to the message field and select Assign a task. Add a - title (required) and an optional description, and choose an assignee from chat participants. You can also leave it unassigned to track it - yourself. - - , - - - Use tasks to stay on top of action items: Tasks are great for follow-ups like “Submit expense report,” “Share - slide deck,” or “Update mileage rate.” They’re perfect for 1:1 check-ins, project updates, or organizing next steps after a team discussion. - - , - - - Edit and manage tasks: Task creators and assignees can comment, edit the title or description, reassign the - task, or mark it as complete. Just click the task to update any details. - - , - - - Tasks stay visible: Each task is shared in the chat where it’s created. When completed, it will be clearly - marked in the chat and can be reopened if needed. - - , - ]} - /> - - ), - }, - }, - }, - search: { - content: ({styles}: {styles: ThemeStyles}) => ( - - Reports Page - - The Reports page helps you explore and filter all reports and related expenses. It complements the Inbox by giving you a complete view of your expense history and - what expenses and reports require your action. Use this page to create and download spending reports, track report actions, and view the recent expense activity on - your workspace(s). - - - Expenses & Reports - - - Managing expenses: Click on any expense row to see its details in a side panel. Use checkboxes to select multiple - expenses, then use bulk actions like Move, Download, or Delete from the action menu. - - , - - - Filters: Looking for something specific? Use filters to narrow things down by date, category, merchant, tag, - workspace, or report status. You can also combine filters with keywords for even more precise results. - - , - - - Sort reports by status: - Draft – Only you can see it - Outstanding – Waiting on someone else - Approved – Ready to - pay - Done or Paid – All wrapped up - - , - - - Download what you need: Generate a report to download filtered expense data as a CSV. Perfect for spreadsheets, - monthly close, or syncing with accounting. - - , - ]} - /> - - Chats - - - Viewing report previews: Each report preview shows up right in your workspace chat with the status, up to 10 - expenses, and buttons like Submit or Approve, depending on your role. - - , - - - Filter chats: Use filters to find the exact chat you’re looking for. - - , - ]} - /> - - To-Do - - - Stay on top of tasks: The To-do section shows exactly what needs your attention. This is your go-to spot to keep - things moving. - - , - - - Action items: Whether you need to submit, approve, or pay expenses, you can click the corresponding action to - complete any outstanding to-dos. - - , - ]} - /> - - Learn More - - - The Reports Page - - , - - - Understanding Reports Statuses and Actions - - , - - - Suggested Search - - , - - - Search and Download Expenses - - , - ]} - /> - - ), - }, - }, - content: () => null, -}; - -export default helpContentMap; -export type {ContentComponent}; diff --git a/src/components/SidePanel/getHelpContent.tsx b/src/components/SidePanel/getHelpContent.tsx deleted file mode 100644 index deeb9af1d9574..0000000000000 --- a/src/components/SidePanel/getHelpContent.tsx +++ /dev/null @@ -1,68 +0,0 @@ -import type {ReactNode} from 'react'; -import React from 'react'; -import {View} from 'react-native'; -import Text from '@components/Text'; -import type {ThemeStyles} from '@styles/index'; -import HelpDiagnosticData from './HelpComponents/HelpDiagnosticData'; -import HelpExpandable from './HelpComponents/HelpExpandable'; -import type {ContentComponent} from './HelpContent/helpContentMap'; -import helpContentMap from './HelpContent/helpContentMap'; - -function getHelpContent(styles: ThemeStyles, route: string, isProduction: boolean, expandedIndex: number, setExpandedIndex: (idx: number) => void): ReactNode { - const routeParts = route.split('/'); - const helpContentComponents: ContentComponent[] = []; - let activeHelpContent = helpContentMap; - let isExactMatch = true; - - for (const part of routeParts) { - if (activeHelpContent?.children?.[part]) { - activeHelpContent = activeHelpContent.children[part]; - if (activeHelpContent.content) { - helpContentComponents.push(activeHelpContent.content); - } - } else { - if (helpContentComponents.length === 0) { - // eslint-disable-next-line react/no-unescaped-entities - helpContentComponents.push(() => We couldn't find any help content for this route.); - } - isExactMatch = false; - break; - } - } - - const content = helpContentComponents - .reverse() - .slice(0, expandedIndex + 2) - .map((HelpContentNode, index) => { - return ( - // eslint-disable-next-line react/no-array-index-key - - {index > 0 && } - setExpandedIndex(index)} - > - - - - ); - }); - - if (isProduction) { - return content; - } - - return ( - - {content} - - ); -} - -export default getHelpContent; diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 26fa736af4884..9cae19b2cbe5c 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2620,38 +2620,6 @@ function isMoneyRequestReport(reportOrID: OnyxInputOrEntry | string, rep return isIOUReport(report) || isExpenseReport(report); } -/** - * Determines the Help Panel report type based on the given report. - */ -function getHelpPaneReportType(report: OnyxEntry, conciergeReportID: string): ValueOf | undefined { - if (!report) { - return undefined; - } - - if (isConciergeChatReport(report, conciergeReportID)) { - return CONST.REPORT.HELP_TYPE.CHAT_CONCIERGE; - } - - if (report?.chatType) { - return getChatType(report); - } - - switch (report?.type) { - case CONST.REPORT.TYPE.EXPENSE: - return CONST.REPORT.HELP_TYPE.EXPENSE_REPORT; - case CONST.REPORT.TYPE.CHAT: - return CONST.REPORT.HELP_TYPE.CHAT; - case CONST.REPORT.TYPE.IOU: - return CONST.REPORT.HELP_TYPE.IOU; - case CONST.REPORT.TYPE.INVOICE: - return CONST.REPORT.HELP_TYPE.INVOICE; - case CONST.REPORT.TYPE.TASK: - return CONST.REPORT.HELP_TYPE.TASK; - default: - return undefined; - } -} - /** * Checks if a report contains only Non-Reimbursable transactions */ @@ -13569,7 +13537,6 @@ export { canBeExported, isExported, hasExportError, - getHelpPaneReportType, hasOnlyNonReimbursableTransactions, getReportLastMessage, getReportLastVisibleActionCreated, diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 9ce647a958623..2cb176146e399 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -306,26 +306,6 @@ function getRequestType(transaction: OnyxEntry): IOURequestType { return CONST.IOU.REQUEST_TYPE.MANUAL; } -/** - * Determines the expense type of a given transaction. - */ -function getExpenseType(transaction: OnyxEntry): ValueOf | undefined { - if (!transaction) { - return undefined; - } - - if (isExpensifyCardTransaction(transaction)) { - if (isPending(transaction)) { - return CONST.IOU.EXPENSE_TYPE.PENDING_EXPENSIFY_CARD; - } - - return CONST.IOU.EXPENSE_TYPE.EXPENSIFY_CARD; - } - - const requestType = getRequestType(transaction); - return requestType as ValueOf; -} - /** * Determines the transaction type based on custom unit name, comment type or card name. * Returns 'distance' for Distance transactions, 'perDiem' for Per Diem International transactions, @@ -2874,7 +2854,6 @@ export { getClearedPendingFields, getDescription, getRequestType, - getExpenseType, getTransactionType, isManualRequest, isScanRequest, diff --git a/src/types/onyx/IOU.ts b/src/types/onyx/IOU.ts index e88a6034e286b..d8422347953f0 100644 --- a/src/types/onyx/IOU.ts +++ b/src/types/onyx/IOU.ts @@ -267,7 +267,7 @@ type Accountant = { }; /** Type of distance expense */ -type DistanceExpenseType = typeof CONST.IOU.EXPENSE_TYPE.DISTANCE_MAP | typeof CONST.IOU.EXPENSE_TYPE.DISTANCE_MANUAL; +type DistanceExpenseType = typeof CONST.IOU.REQUEST_TYPE.DISTANCE_MAP | typeof CONST.IOU.REQUEST_TYPE.DISTANCE_MANUAL; export default IOU; export type {Participant, Split, Attendee, Accountant, SplitExpense, DistanceExpenseType}; diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 5041dd63c9e78..0343eb001b688 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -75,7 +75,6 @@ import { getDisplayNameForParticipant, getDisplayNamesWithTooltips, getHarvestOriginalReportID, - getHelpPaneReportType, getIconsForParticipants, getIndicatedMissingPaymentMethod, getIOUReportActionDisplayMessage, @@ -13260,107 +13259,6 @@ describe('ReportUtils', () => { }); }); - describe('getHelpPaneReportType', () => { - const conciergeReportID = 'concierge-report-456'; - - it('should return undefined for undefined report', () => { - const result = getHelpPaneReportType(undefined, conciergeReportID); - expect(result).toBeUndefined(); - }); - - it('should return CHAT_CONCIERGE for concierge chat report', () => { - const conciergeReport: Report = { - reportID: conciergeReportID, - type: CONST.REPORT.TYPE.CHAT, - }; - - const result = getHelpPaneReportType(conciergeReport, conciergeReportID); - expect(result).toBe(CONST.REPORT.HELP_TYPE.CHAT_CONCIERGE); - }); - - it('should return chatType for report with chatType', () => { - const groupChatReport: Report = { - reportID: 'group-chat-123', - type: CONST.REPORT.TYPE.CHAT, - chatType: CONST.REPORT.CHAT_TYPE.GROUP, - }; - - const result = getHelpPaneReportType(groupChatReport, conciergeReportID); - expect(result).toBe(CONST.REPORT.CHAT_TYPE.GROUP); - }); - - it('should return EXPENSE_REPORT for expense report type', () => { - const expenseReport: Report = { - reportID: 'expense-report-123', - type: CONST.REPORT.TYPE.EXPENSE, - }; - - const result = getHelpPaneReportType(expenseReport, conciergeReportID); - expect(result).toBe(CONST.REPORT.HELP_TYPE.EXPENSE_REPORT); - }); - - it('should return CHAT for chat report type without chatType', () => { - const chatReport: Report = { - reportID: 'chat-report-123', - type: CONST.REPORT.TYPE.CHAT, - }; - - const result = getHelpPaneReportType(chatReport, conciergeReportID); - expect(result).toBe(CONST.REPORT.HELP_TYPE.CHAT); - }); - - it('should return IOU for IOU report type', () => { - const iouReport: Report = { - reportID: 'iou-report-123', - type: CONST.REPORT.TYPE.IOU, - }; - - const result = getHelpPaneReportType(iouReport, conciergeReportID); - expect(result).toBe(CONST.REPORT.HELP_TYPE.IOU); - }); - - it('should return INVOICE for invoice report type', () => { - const invoiceReport: Report = { - reportID: 'invoice-report-123', - type: CONST.REPORT.TYPE.INVOICE, - }; - - const result = getHelpPaneReportType(invoiceReport, conciergeReportID); - expect(result).toBe(CONST.REPORT.HELP_TYPE.INVOICE); - }); - - it('should return TASK for task report type', () => { - const taskReport: Report = { - reportID: 'task-report-123', - type: CONST.REPORT.TYPE.TASK, - }; - - const result = getHelpPaneReportType(taskReport, conciergeReportID); - expect(result).toBe(CONST.REPORT.HELP_TYPE.TASK); - }); - - it('should return undefined for unknown report type', () => { - const unknownReport: Report = { - reportID: 'unknown-report-123', - type: 'unknown' as Report['type'], - }; - - const result = getHelpPaneReportType(unknownReport, conciergeReportID); - expect(result).toBeUndefined(); - }); - - it('should not return CHAT_CONCIERGE when conciergeReportID does not match', () => { - const chatReport: Report = { - reportID: 'regular-chat-123', - type: CONST.REPORT.TYPE.CHAT, - }; - - const result = getHelpPaneReportType(chatReport, conciergeReportID); - // This report has type CHAT but is not the concierge report - expect(result).toBe(CONST.REPORT.HELP_TYPE.CHAT); - }); - }); - describe('createDraftTransactionAndNavigateToParticipantSelector', () => { it('should return early and not navigate when transaction is undefined', async () => { jest.clearAllMocks();