Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement billing banner #43267

Merged
merged 8 commits into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from 7 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
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/components/Icon/Illustrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import CompanyCard from '@assets/images/simple-illustrations/simple-illustration
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 CreditCardEyes from '@assets/images/simple-illustrations/simple-illustration__creditcardeyes.svg';
import EmailAddress from '@assets/images/simple-illustrations/simple-illustration__email-address.svg';
import FolderOpen from '@assets/images/simple-illustrations/simple-illustration__folder-open.svg';
import Gears from '@assets/images/simple-illustrations/simple-illustration__gears.svg';
Expand Down Expand Up @@ -190,4 +191,5 @@ export {
ExpensifyApprovedLogoLight,
SendMoney,
CheckmarkCircle,
CreditCardEyes,
};
5 changes: 5 additions & 0 deletions src/components/Section/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ type SectionProps = Partial<ChildrenProps> & {

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

/** Banner to display at the top of the section */
banner?: ReactNode;
};

function isIllustrationLottieAnimation(illustration: DotLottieAnimation | IconAsset | undefined): illustration is DotLottieAnimation {
Expand Down Expand Up @@ -119,6 +122,7 @@ function Section({
iconWidth,
iconHeight,
renderSubtitle,
banner = null,
}: SectionProps) {
const styles = useThemeStyles();
const theme = useTheme();
Expand All @@ -133,6 +137,7 @@ function Section({

return (
<View style={[styles.pageWrapper, styles.cardSectionContainer, containerStyles, (isCentralPane || !!illustration) && styles.p0]}>
{banner}
{cardLayout === CARD_LAYOUT.ICON_ON_TOP && (
<IconSection
width={iconWidth}
Expand Down
50 changes: 50 additions & 0 deletions src/pages/settings/Subscription/CardSection/BillingBanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';
import {View} from 'react-native';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import * as Illustrations from '@components/Icon/Illustrations';
import Text from '@components/Text';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import variables from '@styles/variables';

type BillingBannerProps = {
title?: string;
subtitle?: string;
isError?: boolean;
shouldShowRedDotIndicator?: boolean;
isTrialActive?: boolean;
};

function BillingBanner({title, subtitle, isError, shouldShowRedDotIndicator, isTrialActive}: BillingBannerProps) {
const styles = useThemeStyles();
const theme = useTheme();

const backgroundStyle = isTrialActive ? styles.trialBannerBackgroundColor : styles.hoveredComponentBG;

const subtitleStyle = isTrialActive ? [] : styles.textSupporting;

return (
<View style={[styles.pv4, styles.ph5, styles.flexRow, styles.gap3, styles.w100, styles.alignItemsCenter, backgroundStyle]}>
<Icon
Copy link
Collaborator

Choose a reason for hiding this comment

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

@Expensify/design Would we have a case where we might not want to show any icon?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's confirm with @dannymcclain for this one too.

Copy link
Contributor

Choose a reason for hiding this comment

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

We currently do not have any cases where we don't have an icon. And playing around with it in Figma, the icon really contributes a lot to the layout so I'm inclined to say we should always include one.

src={isError ? Illustrations.CreditCardEyes : Illustrations.CheckmarkCircle}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the icon should be passed as a prop. Because we're planning to reuse this for RBR from other API failures like change of subscription plan

Copy link
Collaborator

Choose a reason for hiding this comment

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

or may be I am getting confused. This banner is specific to the Card section? and the other RBRs will be handled as different implementation?

Copy link
Contributor Author

@pasyukevich pasyukevich Jun 10, 2024

Choose a reason for hiding this comment

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

We do not need to pass here icon as a prop, for BRB pattern we will pass the shouldShowRedDotIndicator prop (it also displays on a different side)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, currently, this banner is specific

Copy link
Collaborator

Choose a reason for hiding this comment

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

I meant for all the errors it'll always show CreditCardEyes. Wouldn't we want to make this reusable?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we can update this to be more reusable and make it less specific in the future when it would be needed

Copy link
Collaborator

Choose a reason for hiding this comment

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

Fine with that.

width={variables.menuIconSize}
height={variables.menuIconSize}
/>
<View style={[styles.flex1, styles.justifyContentCenter]}>
{title && <Text style={[styles.textStrong]}>{title}</Text>}
{subtitle && <Text style={subtitleStyle}>{subtitle}</Text>}
</View>
{isError && shouldShowRedDotIndicator && (
<Icon
src={Expensicons.DotIndicator}
fill={theme.danger}
/>
)}
</View>
);
}

BillingBanner.displayName = 'BillingBanner';

export default BillingBanner;
10 changes: 10 additions & 0 deletions src/pages/settings/Subscription/CardSection/CardSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import DateUtils from '@libs/DateUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import {isEmptyObject} from '@src/types/utils/EmptyObject';
import BillingBanner from './BillingBanner';
import CardSectionActions from './CardSectionActions';
import CardSectionDataEmpty from './CardSectionDataEmpty';

Expand All @@ -31,6 +32,15 @@ function CardSection() {
isCentralPane
titleStyles={styles.textStrong}
subtitleMuted
banner={
<BillingBanner
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we get rid of this dummy code?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed

title="Your card couldn’t be charged!"
subtitle="Before retrying, please call your bank directly to authorize Expensify charges and remove any holds. Otherwise, try adding a different payment card."
isError // to show error icon
shouldShowRedDotIndicator // to show red dot indicator
isTrialActive
/>
}
>
<View style={[styles.mt8, styles.mb3, styles.flexRow]}>
{!isEmptyObject(defaultCard?.accountData) && (
Expand Down
4 changes: 4 additions & 0 deletions src/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2848,6 +2848,10 @@ const styles = (theme: ThemeColors) =>
width: variables.iconSizeExtraLarge,
},

trialBannerBackgroundColor: {
backgroundColor: theme.trialBannerBackgroundColor,
},

selectCircle: {
width: variables.componentSizeSmall,
height: variables.componentSizeSmall,
Expand Down
1 change: 1 addition & 0 deletions src/styles/theme/themes/dark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const darkTheme = {
ourMentionBG: colors.green600,
tooltipSupportingText: colors.productLight800,
tooltipPrimaryText: colors.productLight900,
trialBannerBackgroundColor: colors.green700,
skeletonLHNIn: colors.productDark400,
skeletonLHNOut: colors.productDark600,
QRLogo: colors.green400,
Expand Down
1 change: 1 addition & 0 deletions src/styles/theme/themes/light.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const lightTheme = {
ourMentionBG: colors.green100,
tooltipSupportingText: colors.productDark800,
tooltipPrimaryText: colors.productDark900,
trialBannerBackgroundColor: colors.green100,
skeletonLHNIn: colors.productLight400,
skeletonLHNOut: colors.productLight600,
QRLogo: colors.green400,
Expand Down
1 change: 1 addition & 0 deletions src/styles/theme/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type ThemeColors = {
ourMentionBG: Color;
tooltipSupportingText: Color;
tooltipPrimaryText: Color;
trialBannerBackgroundColor: Color;
skeletonLHNIn: Color;
skeletonLHNOut: Color;
QRLogo: Color;
Expand Down
Loading