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
Binary file added assets/images/home-testdrive-image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
59 changes: 59 additions & 0 deletions src/components/WidgetContainer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import type {ReactNode} from 'react';
import React from 'react';
import {View} from 'react-native';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import variables from '@styles/variables';
import type IconAsset from '@src/types/utils/IconAsset';
import Icon from './Icon';
import Text from './Text';

type WidgetContainerProps = {
/** The icon to display along with the title */
icon?: IconAsset;

/** The text to display in the title of the widget */
title?: string;

/** Custom color for the title text */
titleColor?: string;

/** The width of the icon. */
iconWidth?: number;

/** The height of the icon. */
iconHeight?: number;

/** The content to display inside the widget container */
children: ReactNode;
};

function WidgetContainer({children, icon, title, titleColor, iconWidth = variables.iconSizeNormal, iconHeight = variables.iconSizeNormal}: WidgetContainerProps) {
const styles = useThemeStyles();
const theme = useTheme();
const {shouldUseNarrowLayout} = useResponsiveLayout();

return (
<View style={styles.widgetContainer}>
<View style={[styles.flexRow, styles.alignItemsStart, styles.mb5, shouldUseNarrowLayout ? styles.mh5 : styles.mh8, shouldUseNarrowLayout ? styles.mt5 : styles.mt8]}>
{!!icon && (
<View style={[styles.flexGrow0, styles.flexShrink0]}>
<Icon
src={icon}
width={iconWidth}
height={iconHeight}
/>
</View>
)}
<View style={[styles.flexShrink1, styles.flexGrow1, styles.flexRow, styles.alignItemsCenter, styles.gap2]}>
{!!title && <Text style={styles.getWidgetContainerTitleStyle(titleColor ?? theme.text)}>{title}</Text>}
</View>
</View>
{children}
</View>
);
}

export type {WidgetContainerProps};
export default WidgetContainer;
10 changes: 10 additions & 0 deletions src/languages/de.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8211,6 +8211,16 @@ Hier ist ein *Testbeleg*, um dir zu zeigen, wie es funktioniert:`,
},
fabGpsTripExplained: 'Zur GPS-Ansicht wechseln (Schnellaktion)',
},
homePage: {
forYou: 'Für dich',
announcements: 'Ankündigungen',
discoverSection: {
title: 'Entdecken',
menuItemTitleNonAdmin: 'Erfahren Sie, wie Sie Ausgaben erstellen und Berichte einreichen.',
menuItemTitleAdmin: 'Erfahren Sie, wie Sie Mitglieder einladen, Genehmigungsworkflows bearbeiten und Firmenkarten abstimmen.',
menuItemDescription: 'Sehen Sie, was Expensify in 2 Minuten kann',
},
},
};
// IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts,
// so if you change it here, please update it there as well.
Expand Down
10 changes: 10 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -988,6 +988,16 @@ const translations = {
description: "We're fine-tuning a few more bits and pieces of New Expensify to accommodate your specific setup. In the meantime, head over to Expensify Classic.",
},
},
homePage: {
forYou: 'For you',
announcements: 'Announcements',
discoverSection: {
title: 'Discover',
menuItemTitleNonAdmin: 'Learn how to create expenses and submit reports.',
menuItemTitleAdmin: 'Learn how to invite members, edit approval workflows, and reconcile company cards.',
Comment thread
mountiny marked this conversation as resolved.
menuItemDescription: 'See what Expensify can do in 2 min',
},
},
allSettingsScreen: {
subscription: 'Subscription',
domains: 'Domains',
Expand Down
10 changes: 10 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,16 @@ const translations: TranslationDeepObject<typeof en> = {
description: 'Estamos ajustando algunos detalles de New Expensify para adaptarla a tu configuración específica. Mientras tanto, dirígete a Expensify Classic.',
},
},
homePage: {
forYou: 'Para ti',
announcements: 'Anuncios',
discoverSection: {
title: 'Descubrir',
menuItemTitleNonAdmin: 'Aprende a crear gastos y enviar informes.',
menuItemTitleAdmin: 'Aprende a invitar a miembros, editar flujos de aprobación y conciliar tarjetas corporativas.',
menuItemDescription: 'Descubre lo que Expensify puede hacer en 2 minutos',
},
Comment on lines +739 to +744

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Lets confirm these @JmillsExpensify

},
allSettingsScreen: {
subscription: 'Suscripcion',
domains: 'Dominios',
Expand Down
10 changes: 10 additions & 0 deletions src/languages/fr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8217,6 +8217,16 @@ Voici un *reçu test* pour vous montrer comment cela fonctionne :`,
},
fabGpsTripExplained: 'Aller à l’écran GPS (action flottante)',
},
homePage: {
forYou: 'Pour vous',
announcements: 'Annonces',
discoverSection: {
title: 'Découvrir',
menuItemTitleNonAdmin: 'Découvrez comment créer des dépenses et soumettre des rapports.',
menuItemTitleAdmin: 'Apprenez à inviter des membres, à modifier les circuits d’approbation et à rapprocher les cartes de l’entreprise.',
menuItemDescription: 'Découvrez ce qu’Expensify peut faire en 2 minutes',
},
},
};
// IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts,
// so if you change it here, please update it there as well.
Expand Down
14 changes: 12 additions & 2 deletions src/languages/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6987,8 +6987,8 @@ Richiedi dettagli di spesa come ricevute e descrizioni, imposta limiti e valori
[CONST.SEARCH.GROUP_BY.CARD]: 'Carta',
[CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID]: 'ID prelievo', //_/\__/_/ \_,_/\__/\__/\_,_/
[CONST.SEARCH.GROUP_BY.CATEGORY]: 'Categoria',
[CONST.SEARCH.GROUP_BY.MERCHANT]: 'Commerciante',
[CONST.SEARCH.GROUP_BY.TAG]: 'Etichetta',
[CONST.SEARCH.GROUP_BY.MERCHANT]: 'Esercente',
[CONST.SEARCH.GROUP_BY.TAG]: 'Tag',
[CONST.SEARCH.GROUP_BY.MONTH]: 'Mese',
},
feed: 'Feed',
Expand Down Expand Up @@ -8197,6 +8197,16 @@ Ecco una *ricevuta di prova* per mostrarti come funziona:`,
},
fabGpsTripExplained: 'Vai alla schermata GPS (azione flottante)',
},
homePage: {
forYou: 'Per te',
announcements: 'Annunci',
discoverSection: {
title: 'Scopri',
menuItemTitleNonAdmin: 'Scopri come creare spese e inviare report.',
menuItemTitleAdmin: 'Scopri come invitare membri, modificare i flussi di approvazione e riconciliare le carte aziendali.',
menuItemDescription: 'Scopri cosa può fare Expensify in 2 minuti',
},
},
};
// IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts,
// so if you change it here, please update it there as well.
Expand Down
14 changes: 12 additions & 2 deletions src/languages/ja.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6923,10 +6923,10 @@ ${reportName}
reimbursable: '精算対象',
purchaseCurrency: '購入通貨',
groupBy: {
[CONST.SEARCH.GROUP_BY.FROM]: '送信者',
[CONST.SEARCH.GROUP_BY.FROM]: '差出人',
[CONST.SEARCH.GROUP_BY.CARD]: 'カード',
[CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID]: '出金ID',
[CONST.SEARCH.GROUP_BY.CATEGORY]: 'カテゴリー',
[CONST.SEARCH.GROUP_BY.CATEGORY]: 'カテゴリ',
[CONST.SEARCH.GROUP_BY.MERCHANT]: '加盟店',
[CONST.SEARCH.GROUP_BY.TAG]: 'タグ',
[CONST.SEARCH.GROUP_BY.MONTH]: '月',
Expand Down Expand Up @@ -8110,6 +8110,16 @@ Expensify の使い方をお見せするための*テストレシート*がこ
},
fabGpsTripExplained: 'GPS画面へ移動(フローティングアクション)',
},
homePage: {
forYou: 'あなた向け',
announcements: 'お知らせ',
discoverSection: {
title: '発見',
menuItemTitleNonAdmin: '経費の作成方法とレポートの提出方法を学びましょう。',
menuItemTitleAdmin: 'メンバーの招待方法、承認ワークフローの編集方法、会社カードの照合方法について学びましょう。',
menuItemDescription: '2 分で Expensify でできることを確認する',
},
},
};
// IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts,
// so if you change it here, please update it there as well.
Expand Down
14 changes: 12 additions & 2 deletions src/languages/nl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6970,8 +6970,8 @@ Vraag verplichte uitgavedetails zoals bonnetjes en beschrijvingen, stel limieten
[CONST.SEARCH.GROUP_BY.CARD]: 'Kaart',
[CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID]: 'Opname-ID',
[CONST.SEARCH.GROUP_BY.CATEGORY]: 'Categorie',
[CONST.SEARCH.GROUP_BY.MERCHANT]: 'Verkoper',
[CONST.SEARCH.GROUP_BY.TAG]: 'Label',
[CONST.SEARCH.GROUP_BY.MERCHANT]: 'Handelaar',
[CONST.SEARCH.GROUP_BY.TAG]: 'Tag',
[CONST.SEARCH.GROUP_BY.MONTH]: 'Maand',
},
feed: 'Feed',
Expand Down Expand Up @@ -8173,6 +8173,16 @@ Hier is een *testbon* om je te laten zien hoe het werkt:`,
},
fabGpsTripExplained: 'Ga naar GPS-scherm (Zwevende actie)',
},
homePage: {
forYou: 'Voor jou',
announcements: 'Aankondigingen',
discoverSection: {
title: 'Ontdek',
menuItemTitleNonAdmin: 'Leer hoe je uitgaven aanmaakt en rapporten indient.',
menuItemTitleAdmin: 'Leer hoe u leden uitnodigt, goedkeuringsworkflows bewerkt en bedrijfskaarten afstemt.',
menuItemDescription: 'Ontdek wat Expensify in 2 minuten kan doen',
},
},
};
// IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts,
// so if you change it here, please update it there as well.
Expand Down
10 changes: 10 additions & 0 deletions src/languages/pl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8159,6 +8159,16 @@ Oto *paragon testowy*, który pokazuje, jak to działa:`,
},
fabGpsTripExplained: 'Przejdź do ekranu GPS (przycisk akcji)',
},
homePage: {
forYou: 'Dla ciebie',
announcements: 'Ogłoszenia',
discoverSection: {
title: 'Odkryj',
menuItemTitleNonAdmin: 'Dowiedz się, jak tworzyć wydatki i składać raporty.',
menuItemTitleAdmin: 'Dowiedz się, jak zapraszać członków, edytować przepływy akceptacji i uzgadniać karty firmowe.',
menuItemDescription: 'Zobacz, co Expensify potrafi w 2 minuty',
},
},
};
// IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts,
// so if you change it here, please update it there as well.
Expand Down
12 changes: 11 additions & 1 deletion src/languages/pt-BR.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6960,7 +6960,7 @@ Exija detalhes de despesas como recibos e descrições, defina limites e padrõe
[CONST.SEARCH.GROUP_BY.CARD]: 'Cartão',
[CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID]: 'ID da retirada',
[CONST.SEARCH.GROUP_BY.CATEGORY]: 'Categoria',
[CONST.SEARCH.GROUP_BY.MERCHANT]: 'Comerciante',
[CONST.SEARCH.GROUP_BY.MERCHANT]: 'Estabelecimento',
[CONST.SEARCH.GROUP_BY.TAG]: 'Etiqueta',
[CONST.SEARCH.GROUP_BY.MONTH]: 'Mês',
},
Expand Down Expand Up @@ -8168,6 +8168,16 @@ Aqui está um *recibo de teste* para mostrar como funciona:`,
},
fabGpsTripExplained: 'Ir para a tela de GPS (Ação flutuante)',
},
homePage: {
forYou: 'Para você',
announcements: 'Anúncios',
discoverSection: {
title: 'Descobrir',
menuItemTitleNonAdmin: 'Aprenda a criar despesas e enviar relatórios.',
menuItemTitleAdmin: 'Aprenda a convidar membros, editar fluxos de aprovação e reconciliar cartões corporativos.',
menuItemDescription: 'Veja o que o Expensify pode fazer em 2 minutos',
},
},
};
// IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts,
// so if you change it here, please update it there as well.
Expand Down
16 changes: 13 additions & 3 deletions src/languages/zh-hans.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6804,10 +6804,10 @@ ${reportName}
purchaseCurrency: '购买货币',
groupBy: {
[CONST.SEARCH.GROUP_BY.FROM]: '来自',
[CONST.SEARCH.GROUP_BY.CARD]: '卡片',
[CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID]: '提现 ID',
[CONST.SEARCH.GROUP_BY.CARD]: '',
[CONST.SEARCH.GROUP_BY.WITHDRAWAL_ID]: '提现编号',
[CONST.SEARCH.GROUP_BY.CATEGORY]: '类别',
[CONST.SEARCH.GROUP_BY.MERCHANT]: '商家',
[CONST.SEARCH.GROUP_BY.MERCHANT]: '商户',
[CONST.SEARCH.GROUP_BY.TAG]: '标签',
[CONST.SEARCH.GROUP_BY.MONTH]: '月',
},
Expand Down Expand Up @@ -7933,6 +7933,16 @@ ${reportName}
locationServicesRequiredModal: {title: '需要访问位置信息', confirm: '打开设置', prompt: '请在设备设置中允许位置访问,以开始 GPS 距离跟踪。'},
fabGpsTripExplained: '前往 GPS 屏幕(悬浮操作)',
},
homePage: {
forYou: '为你',
announcements: '公告',
discoverSection: {
title: '发现',
menuItemTitleNonAdmin: '了解如何创建费用并提交报表。',
menuItemTitleAdmin: '了解如何邀请成员、编辑审批流程以及对公司卡进行对账。',
menuItemDescription: '看看 Expensify 在 2 分钟内能为你做什么',
},
},
};
// IMPORTANT: This line is manually replaced in generate translation files by scripts/generateTranslations.ts,
// so if you change it here, please update it there as well.
Expand Down
2 changes: 1 addition & 1 deletion src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const loadLogOutPreviousUserPage = () => require<ReactComponentModule>('../../..
const loadConciergePage = () => require<ReactComponentModule>('../../../pages/ConciergePage').default;
const loadTrackExpensePage = () => require<ReactComponentModule>('../../../pages/TrackExpensePage').default;
const loadSubmitExpensePage = () => require<ReactComponentModule>('../../../pages/SubmitExpensePage').default;
const loadHomePage = () => require<ReactComponentModule>('../../../pages/HomePage').default;
const loadHomePage = () => require<ReactComponentModule>('../../../pages/home/HomePage').default;
const loadWorkspaceJoinUser = () => require<ReactComponentModule>('@pages/workspace/WorkspaceJoinUserPage').default;

const loadReportSplitNavigator = () => require<ReactComponentModule>('./Navigators/ReportsSplitNavigator').default;
Expand Down
38 changes: 0 additions & 38 deletions src/pages/HomePage.tsx

This file was deleted.

57 changes: 57 additions & 0 deletions src/pages/home/DiscoverSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import {Image, Linking, View} from 'react-native';
import HomeTestDriveImage from '@assets/images/home-testdrive-image.png';
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
import {PressableWithoutFeedback} from '@components/Pressable';
import WidgetContainer from '@components/WidgetContainer';
import useIsPaidPolicyAdmin from '@hooks/useIsPaidPolicyAdmin';
import useLocalize from '@hooks/useLocalize';
import useOnyx from '@hooks/useOnyx';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useThemeStyles from '@hooks/useThemeStyles';
import {getTestDriveURL} from '@libs/TourUtils';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';

const MAX_NUMBER_OF_LINES_TITLE = 4;

function DiscoverSection() {
const {translate} = useLocalize();
const {shouldUseNarrowLayout} = useResponsiveLayout();
const isCurrentUserPolicyAdmin = useIsPaidPolicyAdmin();
const [introSelected] = useOnyx(ONYXKEYS.NVP_INTRO_SELECTED, {canBeMissing: true});
const styles = useThemeStyles();

const handlePress = () => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

❌ CONSISTENCY-5 (docs)

The Linking.openURL call lacks error handling. If the URL is malformed or the system cannot open the link, the error will be silent.

Suggested fix:
Add error handling and user feedback:

const handlePress = () => {
    const url = getTestDriveURL(shouldUseNarrowLayout, introSelected, isCurrentUserPolicyAdmin);
    Linking.openURL(url).catch((error) => {
        Log.error('Failed to open test drive URL', error);
        // Optionally show user feedback
    });
};

Please rate this suggestion with 👍 or 👎 to help us improve! Reactions are used to monitor reviewer efficiency.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Technically correct but inconsistent with existing patterns. The codebase doesn't do this anywhere else.

Linking.openURL(getTestDriveURL(shouldUseNarrowLayout, introSelected, isCurrentUserPolicyAdmin));
};

return (
<WidgetContainer title={translate('homePage.discoverSection.title')}>
<PressableWithoutFeedback
onPress={handlePress}
accessibilityRole={CONST.ROLE.BUTTON}
accessibilityLabel={translate('homePage.discoverSection.title')}
style={[shouldUseNarrowLayout ? styles.mh5 : styles.mh8, styles.mb5]}
>
<View style={[styles.br2, styles.overflowHidden]}>
<Image
source={HomeTestDriveImage}
style={styles.discoverSectionImage}
/>
</View>
</PressableWithoutFeedback>
<MenuItemWithTopDescription
shouldShowRightIcon
title={isCurrentUserPolicyAdmin ? translate('homePage.discoverSection.menuItemTitleAdmin') : translate('homePage.discoverSection.menuItemTitleNonAdmin')}
description={translate('homePage.discoverSection.menuItemDescription')}
onPress={handlePress}
style={shouldUseNarrowLayout ? styles.mb2 : styles.mb5}
wrapperStyle={shouldUseNarrowLayout ? styles.pl5 : styles.pl8}
numberOfLinesTitle={MAX_NUMBER_OF_LINES_TITLE}
/>
</WidgetContainer>
);
}

export default DiscoverSection;
Loading
Loading