diff --git a/assets/images/themeDependent/empty-state_receipt-add-small--dark.svg b/assets/images/themeDependent/empty-state_receipt-add-small--dark.svg new file mode 100644 index 000000000000..8071d7a11272 --- /dev/null +++ b/assets/images/themeDependent/empty-state_receipt-add-small--dark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/assets/images/themeDependent/empty-state_receipt-add-small--light.svg b/assets/images/themeDependent/empty-state_receipt-add-small--light.svg new file mode 100644 index 000000000000..2f4a04861f7c --- /dev/null +++ b/assets/images/themeDependent/empty-state_receipt-add-small--light.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index 150c78ac0e98..b7803d18fb78 100644 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -429,6 +429,7 @@ function MoneyRequestConfirmationList({ const sections = useConfirmationSections({ isTypeSplit, + isTypeInvoice, shouldHideToSection, shouldForceTopEmptySections, participantRowErrors, diff --git a/src/components/MoneyRequestConfirmationList/hooks/useConfirmationSections.ts b/src/components/MoneyRequestConfirmationList/hooks/useConfirmationSections.ts index d029d311fa05..d078e84129cc 100644 --- a/src/components/MoneyRequestConfirmationList/hooks/useConfirmationSections.ts +++ b/src/components/MoneyRequestConfirmationList/hooks/useConfirmationSections.ts @@ -18,6 +18,9 @@ type UseConfirmationSectionsParams = { /** Whether the current IOU type is split */ isTypeSplit: boolean; + /** Whether the current IOU type is invoice (keeps the "To" header, which pairs with the invoice "Send from" field) */ + isTypeInvoice?: boolean; + /** Whether the "to" section should be hidden (used when adding directly to a report) */ shouldHideToSection: boolean; @@ -55,6 +58,7 @@ type UseConfirmationSectionsParams = { */ function useConfirmationSections({ isTypeSplit, + isTypeInvoice = false, shouldHideToSection, shouldForceTopEmptySections = false, participantRowErrors, @@ -104,7 +108,7 @@ function useConfirmationSections({ ]; options.push({ - title: selectedParticipants.length > 0 ? translate('common.to') : undefined, + title: isTypeInvoice && selectedParticipants.length > 0 ? translate('common.to') : undefined, data: participantRows, sectionIndex: 0, }); diff --git a/src/components/MoneyRequestConfirmationListFooter/sections/ReceiptSection.tsx b/src/components/MoneyRequestConfirmationListFooter/sections/ReceiptSection.tsx index 1c23e7d8a618..4a13e18c130e 100644 --- a/src/components/MoneyRequestConfirmationListFooter/sections/ReceiptSection.tsx +++ b/src/components/MoneyRequestConfirmationListFooter/sections/ReceiptSection.tsx @@ -131,7 +131,8 @@ function ReceiptSection({ } Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_SCAN.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID, Navigation.getActiveRoute())); }} - style={[compact.isCompactMode ? undefined : styles.mv3, compact.isCompactMode && compact.compactReceiptStyle ? compact.compactReceiptStyle : styles.moneyRequestViewImage]} + isCompact={!compact.isCompactMode} + style={[compact.isCompactMode ? undefined : styles.mt2, compact.isCompactMode && compact.compactReceiptStyle ? compact.compactReceiptStyle : undefined]} /> ); } diff --git a/src/components/ReceiptEmptyState.tsx b/src/components/ReceiptEmptyState.tsx index f642ef1a1896..3ab0d0deee79 100644 --- a/src/components/ReceiptEmptyState.tsx +++ b/src/components/ReceiptEmptyState.tsx @@ -2,6 +2,7 @@ import useFilesValidation from '@hooks/useFilesValidation'; import {useMemoizedLazyExpensifyIcons} from '@hooks/useLazyAsset'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; +import useThemeIllustrations from '@hooks/useThemeIllustrations'; import useThemeStyles from '@hooks/useThemeStyles'; import variables from '@styles/variables'; @@ -37,6 +38,9 @@ type ReceiptEmptyStateProps = { /** Whether the receipt empty state should extend to the full height of the container. */ shouldUseFullHeight?: boolean; + /** Whether to render the small banner layout (icon + label in a row) instead of the full-height box */ + isCompact?: boolean; + style?: StyleProp; /** Callback to be called when the image loads */ @@ -75,6 +79,7 @@ function ReceiptEmptyState({ isThumbnail = false, isInMoneyRequestView = false, shouldUseFullHeight = false, + isCompact = false, style, onLoad, isDisplayedInWideRHP = false, @@ -83,21 +88,24 @@ function ReceiptEmptyState({ const styles = useThemeStyles(); const {translate} = useLocalize(); const theme = useTheme(); + const illustrations = useThemeIllustrations(); const isLoadedRef = useRef(false); const icons = useMemoizedLazyExpensifyIcons(['Receipt']); const {validateFiles, PDFValidationComponent, ErrorModal} = useFilesValidation(setReceiptFile); const Wrapper = onPress ? PressableWithoutFeedback : View; - const containerStyle = [ - styles.alignItemsCenter, - styles.justifyContentCenter, - styles.moneyRequestViewImage, - isDisplayedInWideRHP && !disabled && styles.pb5, - isThumbnail && !isInMoneyRequestView ? styles.moneyRequestAttachReceiptThumbnail : styles.moneyRequestAttachReceipt, - shouldUseFullHeight && styles.receiptEmptyStateFullHeight, - style, - ]; + const containerStyle = isCompact + ? [styles.alignItemsCenter, styles.justifyContentCenter, styles.receiptEmptyStateCompact, styles.moneyRequestAttachReceipt, style] + : [ + styles.alignItemsCenter, + styles.justifyContentCenter, + styles.moneyRequestViewImage, + isDisplayedInWideRHP && !disabled && styles.pb5, + isThumbnail && !isInMoneyRequestView ? styles.moneyRequestAttachReceiptThumbnail : styles.moneyRequestAttachReceipt, + shouldUseFullHeight && styles.receiptEmptyStateFullHeight, + style, + ]; useEffect(() => { if (isLoadedRef.current) { @@ -128,33 +136,44 @@ function ReceiptEmptyState({ > {PDFValidationComponent} {ErrorModal} - - - - - {!isThumbnail && ( - - - + {isCompact ? ( + + + {translate('dropzone.addReceipt')} + + ) : ( + + + + + {!isThumbnail && ( + + + + )} + + {!isThumbnail && isDisplayedInWideRHP && ( + <> + {translate('receipt.addAReceipt.phrase1')} + {translate('receipt.addAReceipt.phrase2')} + )} - {!isThumbnail && isDisplayedInWideRHP && ( - <> - {translate('receipt.addAReceipt.phrase1')} - {translate('receipt.addAReceipt.phrase2')} - - )} - + )} {isDisplayedInWideRHP && !disabled && } )} diff --git a/src/styles/index.ts b/src/styles/index.ts index a0ef67de052e..c2cbb10b30ad 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4957,6 +4957,14 @@ const staticStyles = (theme: ThemeColors) => receiptEmptyStateFullHeight: {height: '100%', borderRadius: 12}, + receiptEmptyStateCompact: { + ...spacing.mh4, + overflow: 'hidden', + borderRadius: variables.componentBorderRadiusNormal, + height: 52, + maxWidth: '100%', + }, + moneyRequestAttachReceiptThumbnailIcon: { position: 'absolute', bottom: -4, diff --git a/src/styles/theme/illustrations/themes/dark.ts b/src/styles/theme/illustrations/themes/dark.ts index 6493abd574db..b61094926123 100644 --- a/src/styles/theme/illustrations/themes/dark.ts +++ b/src/styles/theme/illustrations/themes/dark.ts @@ -5,6 +5,7 @@ import FileImportTable from '@assets/images/companyCards/table-dark.svg'; import ExpensifyApprovedBadge from '@assets/images/exfy_approved_badge.svg'; import ExpensifyApprovedLogo from '@assets/images/subscription-details__approvedlogo.svg'; import EmptyStateBackgroundImage from '@assets/images/themeDependent/empty-state_background-fade-dark.svg'; +import ReceiptAddSmall from '@assets/images/themeDependent/empty-state_receipt-add-small--dark.svg'; import ExampleCheckEN from '@assets/images/themeDependent/example-check-image-dark-en.png'; import ExampleCheckES from '@assets/images/themeDependent/example-check-image-dark-es.png'; import WorkspaceProfile from '@assets/images/workspace-profile.png'; @@ -13,6 +14,7 @@ import type IllustrationsType from '@styles/theme/illustrations/types'; const illustrations = { EmptyStateBackgroundImage, + ReceiptAddSmall, ExampleCheckEN, ExampleCheckES, WorkspaceProfile, diff --git a/src/styles/theme/illustrations/themes/light.ts b/src/styles/theme/illustrations/themes/light.ts index 30ca388e11f7..d2ae7863453a 100644 --- a/src/styles/theme/illustrations/themes/light.ts +++ b/src/styles/theme/illustrations/themes/light.ts @@ -5,6 +5,7 @@ import FileImportTable from '@assets/images/companyCards/table-light.svg'; import ExpensifyApprovedBadge from '@assets/images/exfy_approved_badge.svg'; import ExpensifyApprovedLogo from '@assets/images/subscription-details__approvedlogo--light.svg'; import EmptyStateBackgroundImage from '@assets/images/themeDependent/empty-state_background-fade-light.svg'; +import ReceiptAddSmall from '@assets/images/themeDependent/empty-state_receipt-add-small--light.svg'; import ExampleCheckEN from '@assets/images/themeDependent/example-check-image-light-en.png'; import ExampleCheckES from '@assets/images/themeDependent/example-check-image-light-es.png'; import WorkspaceProfile from '@assets/images/workspace-profile-light.png'; @@ -13,6 +14,7 @@ import type IllustrationsType from '@styles/theme/illustrations/types'; const illustrations = { EmptyStateBackgroundImage, + ReceiptAddSmall, ExampleCheckEN, ExampleCheckES, WorkspaceProfile, diff --git a/src/styles/theme/illustrations/types.ts b/src/styles/theme/illustrations/types.ts index f3ea58ff33c4..94198e2e6d70 100644 --- a/src/styles/theme/illustrations/types.ts +++ b/src/styles/theme/illustrations/types.ts @@ -6,6 +6,7 @@ import type {SvgProps} from 'react-native-svg'; type IllustrationsType = { EmptyStateBackgroundImage: FC; + ReceiptAddSmall: FC; ExampleCheckES: ImageSourcePropType; ExampleCheckEN: ImageSourcePropType; WorkspaceProfile: ImageSourcePropType;