From 6f95d5b246c90b27b2ad16bb7bcb2c52208e7d45 Mon Sep 17 00:00:00 2001
From: cdOut <88325488+cdOut@users.noreply.github.com>
Date: Thu, 7 Dec 2023 14:39:44 +0100
Subject: [PATCH 01/11] add Educational Interstitial as popup and RHP
---
.../simple-illustration__commentbubbles.svg | 22 ++++
.../simple-illustration__hourglass.svg | 56 +++++++++
.../simple-illustration__trashcan.svg | 52 +++++++++
src/ROUTES.ts | 1 +
src/components/Icon/Illustrations.ts | 6 +
src/components/ProcessMoneyRequestHoldMenu.js | 106 ++++++++++++++++++
src/languages/en.ts | 8 ++
.../AppNavigator/ModalStackNavigators.js | 5 +
.../Navigators/RightModalNavigator.js | 4 +
src/libs/Navigation/linkingConfig.js | 5 +
src/pages/ProcessMoneyRequestHoldPage.js | 94 ++++++++++++++++
src/styles/styles.ts | 15 +++
src/styles/variables.ts | 1 +
13 files changed, 375 insertions(+)
create mode 100644 assets/images/simple-illustrations/simple-illustration__commentbubbles.svg
create mode 100644 assets/images/simple-illustrations/simple-illustration__hourglass.svg
create mode 100644 assets/images/simple-illustrations/simple-illustration__trashcan.svg
create mode 100644 src/components/ProcessMoneyRequestHoldMenu.js
create mode 100644 src/pages/ProcessMoneyRequestHoldPage.js
diff --git a/assets/images/simple-illustrations/simple-illustration__commentbubbles.svg b/assets/images/simple-illustrations/simple-illustration__commentbubbles.svg
new file mode 100644
index 000000000000..829d3ee2e3fe
--- /dev/null
+++ b/assets/images/simple-illustrations/simple-illustration__commentbubbles.svg
@@ -0,0 +1,22 @@
+
+
+
diff --git a/assets/images/simple-illustrations/simple-illustration__hourglass.svg b/assets/images/simple-illustrations/simple-illustration__hourglass.svg
new file mode 100644
index 000000000000..539e1e45b795
--- /dev/null
+++ b/assets/images/simple-illustrations/simple-illustration__hourglass.svg
@@ -0,0 +1,56 @@
+
+
+
diff --git a/assets/images/simple-illustrations/simple-illustration__trashcan.svg b/assets/images/simple-illustrations/simple-illustration__trashcan.svg
new file mode 100644
index 000000000000..4e66efa0a67e
--- /dev/null
+++ b/assets/images/simple-illustrations/simple-illustration__trashcan.svg
@@ -0,0 +1,52 @@
+
+
+
diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index 26589a3db0e0..a4ce8e46df6c 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -379,6 +379,7 @@ export default {
route: 'referral/:contentType',
getRoute: (contentType: string) => `referral/${contentType}`,
},
+ PROCESS_MONEY_REQUEST_HOLD: 'hold-request-educational',
// These are some one-off routes that will be removed once they're no longer needed (see GH issues for details)
SAASTR: 'saastr',
diff --git a/src/components/Icon/Illustrations.ts b/src/components/Icon/Illustrations.ts
index 440350895826..6b486c7407b4 100644
--- a/src/components/Icon/Illustrations.ts
+++ b/src/components/Icon/Illustrations.ts
@@ -30,11 +30,13 @@ import BankArrow from '@assets/images/simple-illustrations/simple-illustration__
import PinkBill from '@assets/images/simple-illustrations/simple-illustration__bill.svg';
import ChatBubbles from '@assets/images/simple-illustrations/simple-illustration__chatbubbles.svg';
import CoffeeMug from '@assets/images/simple-illustrations/simple-illustration__coffeemug.svg';
+import CommentBubbles from '@assets/images/simple-illustrations/simple-illustration__commentbubbles.svg';
import ConciergeBubble from '@assets/images/simple-illustrations/simple-illustration__concierge-bubble.svg';
import ConciergeNew from '@assets/images/simple-illustrations/simple-illustration__concierge.svg';
import CreditCardsNew from '@assets/images/simple-illustrations/simple-illustration__credit-cards.svg';
import EmailAddress from '@assets/images/simple-illustrations/simple-illustration__email-address.svg';
import HandEarth from '@assets/images/simple-illustrations/simple-illustration__handearth.svg';
+import Hourglass from '@assets/images/simple-illustrations/simple-illustration__hourglass.svg';
import InvoiceBlue from '@assets/images/simple-illustrations/simple-illustration__invoice.svg';
import LockOpen from '@assets/images/simple-illustrations/simple-illustration__lockopen.svg';
import Luggage from '@assets/images/simple-illustrations/simple-illustration__luggage.svg';
@@ -47,6 +49,7 @@ import SanFrancisco from '@assets/images/simple-illustrations/simple-illustratio
import ShieldYellow from '@assets/images/simple-illustrations/simple-illustration__shield.svg';
import ThumbsUpStars from '@assets/images/simple-illustrations/simple-illustration__thumbsupstars.svg';
import TrackShoe from '@assets/images/simple-illustrations/simple-illustration__track-shoe.svg';
+import TrashCan from '@assets/images/simple-illustrations/simple-illustration__trashcan.svg';
import TreasureChest from '@assets/images/simple-illustrations/simple-illustration__treasurechest.svg';
export {
@@ -100,4 +103,7 @@ export {
Hands,
HandEarth,
SmartScan,
+ Hourglass,
+ CommentBubbles,
+ TrashCan,
};
diff --git a/src/components/ProcessMoneyRequestHoldMenu.js b/src/components/ProcessMoneyRequestHoldMenu.js
new file mode 100644
index 000000000000..78da0a5ba834
--- /dev/null
+++ b/src/components/ProcessMoneyRequestHoldMenu.js
@@ -0,0 +1,106 @@
+import _ from 'lodash';
+import PropTypes from 'prop-types';
+import React, {useMemo} from 'react';
+import {View} from 'react-native';
+import useLocalize from '@hooks/useLocalize';
+import useThemeStyles from '@styles/useThemeStyles';
+import variables from '@styles/variables';
+import Button from './Button';
+import Icon from './Icon';
+import * as Illustrations from './Icon/Illustrations';
+import Popover from './Popover';
+import refPropTypes from './refPropTypes';
+import Text from './Text';
+
+const propTypes = {
+ isVisible: PropTypes.bool.isRequired,
+ onClose: PropTypes.func.isRequired,
+ onConfirm: PropTypes.func.isRequired,
+ anchorPosition: PropTypes.shape({
+ horizontal: PropTypes.number,
+ vertical: PropTypes.number,
+ }),
+ anchorRef: refPropTypes,
+};
+
+const defaultProps = {
+ anchorPosition: {},
+ anchorRef: () => {},
+};
+
+function ProcessMoneyRequestHoldMenu({isVisible, onClose, onConfirm, anchorPosition, anchorRef}) {
+ const {translate} = useLocalize();
+ const styles = useThemeStyles();
+
+ const holdMenuSections = useMemo(() => {
+ const baseHoldMenuSections = [
+ {
+ icon: Illustrations.Hourglass,
+ titleTranslationKey: 'iou.whatIsHoldTitle',
+ descriptionTranslationKey: 'iou.whatIsHoldExplain',
+ },
+ {
+ icon: Illustrations.CommentBubbles,
+ titleTranslationKey: 'iou.holdIsTemporaryTitle',
+ descriptionTranslationKey: 'iou.holdIsTemporaryExplain',
+ },
+ {
+ icon: Illustrations.TrashCan,
+ titleTranslationKey: 'iou.deleteHoldTitle',
+ descriptionTranslationKey: 'iou.deleteHoldExplain',
+ },
+ ];
+
+ return _.map(baseHoldMenuSections, (section, index) => (
+
+
+
+ {translate(section.titleTranslationKey)}
+
+ {translate(section.descriptionTranslationKey)}
+
+
+
+ ));
+ }, [styles, translate]);
+
+ return (
+
+
+
+ {translate('iou.holdEducationalTitle')}
+ {translate('iou.hold')}
+
+ {holdMenuSections}
+
+
+
+ );
+}
+
+ProcessMoneyRequestHoldMenu.propTypes = propTypes;
+ProcessMoneyRequestHoldMenu.defaultProps = defaultProps;
+ProcessMoneyRequestHoldMenu.displayName = 'ProcessMoneyRequestHoldMenu';
+
+export default ProcessMoneyRequestHoldMenu;
diff --git a/src/languages/en.ts b/src/languages/en.ts
index 4c6ea25eb2c8..e50e65b912ed 100755
--- a/src/languages/en.ts
+++ b/src/languages/en.ts
@@ -599,6 +599,14 @@ export default {
},
waitingOnEnabledWallet: ({submitterDisplayName}: WaitingOnBankAccountParams) => `Started settling up, payment is held until ${submitterDisplayName} enables their Wallet`,
enableWallet: 'Enable Wallet',
+ hold: 'Hold',
+ holdEducationalTitle: 'This request is on',
+ whatIsHoldTitle: 'What is hold?',
+ whatIsHoldExplain: 'Hold is our way of streamlining financial collaboration. "Reject" is so harsh!',
+ holdIsTemporaryTitle: 'Hold is usually temporary',
+ holdIsTemporaryExplain: "Because hold is used to clear up confusion or clarify an important detail before payment, it's not permanent.",
+ deleteHoldTitle: "Delete whatever won't be paid",
+ deleteHoldExplain: "In the rare case where something is put on hold and won't be paid, it's on the person requesting payment to delete it.",
},
notificationPreferencesPage: {
header: 'Notification preferences',
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
index 01573cb434b4..deabe45d6c2f 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
@@ -230,6 +230,10 @@ const ReferralModalStackNavigator = createModalStackNavigator({
Referral_Details: () => require('../../../pages/ReferralDetailsPage').default,
});
+const ProcessMoneyRequestHoldStackNavigator = createModalStackNavigator({
+ ProcessMoneyRequestHold_Root: () => require('../../../pages/ProcessMoneyRequestHoldPage').default,
+});
+
export {
MoneyRequestModalStackNavigator,
SplitDetailsModalStackNavigator,
@@ -256,4 +260,5 @@ export {
RoomMembersModalStackNavigator,
RoomInviteModalStackNavigator,
ReferralModalStackNavigator,
+ ProcessMoneyRequestHoldStackNavigator,
};
diff --git a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js
index b8e04a6ff9e8..469a4baac123 100644
--- a/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js
+++ b/src/libs/Navigation/AppNavigator/Navigators/RightModalNavigator.js
@@ -123,6 +123,10 @@ function RightModalNavigator(props) {
name="Private_Notes"
component={ModalStackNavigators.PrivateNotesModalStackNavigator}
/>
+
diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js
index e0ac35c957a3..fccce91166ab 100644
--- a/src/libs/Navigation/linkingConfig.js
+++ b/src/libs/Navigation/linkingConfig.js
@@ -443,6 +443,11 @@ export default {
Referral_Details: ROUTES.REFERRAL_DETAILS_MODAL.route,
},
},
+ ProcessMoneyRequestHold: {
+ screens: {
+ ProcessMoneyRequestHold_Root: ROUTES.PROCESS_MONEY_REQUEST_HOLD,
+ },
+ },
},
},
},
diff --git a/src/pages/ProcessMoneyRequestHoldPage.js b/src/pages/ProcessMoneyRequestHoldPage.js
new file mode 100644
index 000000000000..ba128ccd3caa
--- /dev/null
+++ b/src/pages/ProcessMoneyRequestHoldPage.js
@@ -0,0 +1,94 @@
+import _ from 'lodash';
+import PropTypes from 'prop-types';
+import React, {useMemo} from 'react';
+import {View} from 'react-native';
+import Button from '@components/Button';
+import HeaderPageLayout from '@components/HeaderPageLayout';
+import Icon from '@components/Icon';
+import * as Illustrations from '@components/Icon/Illustrations';
+import Text from '@components/Text';
+import useLocalize from '@hooks/useLocalize';
+import useThemeStyles from '@styles/useThemeStyles';
+import variables from '@styles/variables';
+
+const propTypes = {
+ onClose: PropTypes.func.isRequired,
+ onConfirm: PropTypes.func.isRequired,
+};
+
+function ProcessMoneyRequestHoldPage({onClose, onConfirm}) {
+ const styles = useThemeStyles();
+ const {translate} = useLocalize();
+
+ const interstitialSections = useMemo(() => {
+ const baseInterstitialSections = [
+ {
+ icon: Illustrations.Hourglass,
+ titleTranslationKey: 'iou.whatIsHoldTitle',
+ descriptionTranslationKey: 'iou.whatIsHoldExplain',
+ },
+ {
+ icon: Illustrations.CommentBubbles,
+ titleTranslationKey: 'iou.holdIsTemporaryTitle',
+ descriptionTranslationKey: 'iou.holdIsTemporaryExplain',
+ },
+ {
+ icon: Illustrations.TrashCan,
+ titleTranslationKey: 'iou.deleteHoldTitle',
+ descriptionTranslationKey: 'iou.deleteHoldExplain',
+ },
+ ];
+
+ return _.map(baseInterstitialSections, (section) => (
+
+
+
+ {translate(section.titleTranslationKey)}
+
+ {translate(section.descriptionTranslationKey)}
+
+
+
+ ));
+ }, [styles, translate]);
+
+ const footerComponent = useMemo(
+ () => (
+
+ ),
+ [onConfirm, translate],
+ );
+
+ return (
+
+
+
+ {translate('iou.holdEducationalTitle')}
+ {translate('iou.hold')}
+
+ {interstitialSections}
+
+
+ );
+}
+
+ProcessMoneyRequestHoldPage.propTypes = propTypes;
+ProcessMoneyRequestHoldPage.displayName = 'StatusPage';
+
+export default ProcessMoneyRequestHoldPage;
diff --git a/src/styles/styles.ts b/src/styles/styles.ts
index c1b78a224eb3..2572526d6d9c 100644
--- a/src/styles/styles.ts
+++ b/src/styles/styles.ts
@@ -3907,6 +3907,21 @@ const styles = (theme: ThemeColors) =>
marginBottom: 16,
},
+ holdRequestInline: {
+ ...headlineFont,
+ ...whiteSpace.preWrap,
+ color: theme.heading,
+ fontSize: variables.fontSizeXLarge,
+ lineHeight: variables.lineHeightXXLarge,
+
+ backgroundColor: colors.red,
+ borderRadius: variables.componentBorderRadiusMedium,
+ overflow: 'hidden',
+
+ paddingHorizontal: 8,
+ paddingVertical: 4,
+ },
+
walletCard: {
borderRadius: variables.componentBorderRadiusLarge,
position: 'relative',
diff --git a/src/styles/variables.ts b/src/styles/variables.ts
index 18800f5748d9..3289b26bf51f 100644
--- a/src/styles/variables.ts
+++ b/src/styles/variables.ts
@@ -191,4 +191,5 @@ export default {
cardPreviewHeight: 148,
cardPreviewWidth: 235,
cardNameWidth: 156,
+ holdMenuIconSize: 64,
} as const;
From ef4a612c612a8658ddb1a6d1dfc399886a1db293 Mon Sep 17 00:00:00 2001
From: cdOut <88325488+cdOut@users.noreply.github.com>
Date: Tue, 12 Dec 2023 17:31:53 +0100
Subject: [PATCH 02/11] separate the section list to avoid code repetition
---
src/components/HoldMenuSectionList.js | 59 +++++++++++++++++++
src/components/ProcessMoneyRequestHoldMenu.js | 52 +---------------
src/pages/ProcessMoneyRequestHoldPage.js | 47 +--------------
3 files changed, 64 insertions(+), 94 deletions(-)
create mode 100644 src/components/HoldMenuSectionList.js
diff --git a/src/components/HoldMenuSectionList.js b/src/components/HoldMenuSectionList.js
new file mode 100644
index 000000000000..0b36183ce9ef
--- /dev/null
+++ b/src/components/HoldMenuSectionList.js
@@ -0,0 +1,59 @@
+import _ from 'lodash';
+import React from 'react';
+import {View} from 'react-native';
+import useLocalize from '@hooks/useLocalize';
+import useThemeStyles from '@styles/useThemeStyles';
+import variables from '@styles/variables';
+import Icon from './Icon';
+import * as Illustrations from './Icon/Illustrations';
+
+function HoldMenuSectionList() {
+ const {translate} = useLocalize();
+ const styles = useThemeStyles();
+
+ const holdMenuSections = [
+ {
+ icon: Illustrations.Hourglass,
+ titleTranslationKey: 'iou.whatIsHoldTitle',
+ descriptionTranslationKey: 'iou.whatIsHoldExplain',
+ },
+ {
+ icon: Illustrations.CommentBubbles,
+ titleTranslationKey: 'iou.holdIsTemporaryTitle',
+ descriptionTranslationKey: 'iou.holdIsTemporaryExplain',
+ },
+ {
+ icon: Illustrations.TrashCan,
+ titleTranslationKey: 'iou.deleteHoldTitle',
+ descriptionTranslationKey: 'iou.deleteHoldExplain',
+ },
+ ];
+
+ return (
+ <>
+ {_.map(holdMenuSections, (section) => (
+
+
+
+ {translate(section.titleTranslationKey)}
+
+ {translate(section.descriptionTranslationKey)}
+
+
+
+ ))}
+ >
+ );
+}
+
+HoldMenuSectionList.displayName = 'HoldMenuSectionList';
+
+export default HoldMenuSectionList;
diff --git a/src/components/ProcessMoneyRequestHoldMenu.js b/src/components/ProcessMoneyRequestHoldMenu.js
index 78da0a5ba834..ffbf377c25d6 100644
--- a/src/components/ProcessMoneyRequestHoldMenu.js
+++ b/src/components/ProcessMoneyRequestHoldMenu.js
@@ -1,13 +1,10 @@
-import _ from 'lodash';
import PropTypes from 'prop-types';
-import React, {useMemo} from 'react';
+import React from 'react';
import {View} from 'react-native';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@styles/useThemeStyles';
-import variables from '@styles/variables';
import Button from './Button';
-import Icon from './Icon';
-import * as Illustrations from './Icon/Illustrations';
+import HoldMenuSectionList from './HoldMenuSectionList';
import Popover from './Popover';
import refPropTypes from './refPropTypes';
import Text from './Text';
@@ -32,49 +29,6 @@ function ProcessMoneyRequestHoldMenu({isVisible, onClose, onConfirm, anchorPosit
const {translate} = useLocalize();
const styles = useThemeStyles();
- const holdMenuSections = useMemo(() => {
- const baseHoldMenuSections = [
- {
- icon: Illustrations.Hourglass,
- titleTranslationKey: 'iou.whatIsHoldTitle',
- descriptionTranslationKey: 'iou.whatIsHoldExplain',
- },
- {
- icon: Illustrations.CommentBubbles,
- titleTranslationKey: 'iou.holdIsTemporaryTitle',
- descriptionTranslationKey: 'iou.holdIsTemporaryExplain',
- },
- {
- icon: Illustrations.TrashCan,
- titleTranslationKey: 'iou.deleteHoldTitle',
- descriptionTranslationKey: 'iou.deleteHoldExplain',
- },
- ];
-
- return _.map(baseHoldMenuSections, (section, index) => (
-
-
-
- {translate(section.titleTranslationKey)}
-
- {translate(section.descriptionTranslationKey)}
-
-
-
- ));
- }, [styles, translate]);
-
return (
{translate('iou.holdEducationalTitle')}
{translate('iou.hold')}
- {holdMenuSections}
+