Skip to content

Commit

Permalink
Merge pull request #4220 from parasharrajat/walletbadge
Browse files Browse the repository at this point in the history
Added Balance badge to the Settings page
  • Loading branch information
Jag96 authored Jul 28, 2021
2 parents 0b6263b + 68cc9ce commit b08f80f
Show file tree
Hide file tree
Showing 6 changed files with 120 additions and 41 deletions.
63 changes: 63 additions & 0 deletions src/components/Badge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import {Pressable, View} from 'react-native';
import PropTypes from 'prop-types';
import styles, {getBadgeColorStyle} from '../styles/styles';
import Text from './Text';

const propTypes = {
/** Is Success type */
success: PropTypes.bool,

/** Is Error type */
error: PropTypes.bool,

/** Whether badge is clickable */
pressable: PropTypes.bool,

/** Text to display in the Badge */
text: PropTypes.string.isRequired,

/** Styles for Badge */
badgeStyles: PropTypes.arrayOf(PropTypes.object),

/** Callback to be called on onPress */
onPress: PropTypes.func,
};

const defaultProps = {
success: false,
error: false,
pressable: false,
badgeStyles: [],
onPress: undefined,
};

const Badge = (props) => {
const textStyles = props.success || props.error ? styles.textWhite : undefined;
const Wrapper = props.pressable ? Pressable : View;
const wrapperStyles = ({pressed}) => ([
styles.badge,
styles.ml2,
getBadgeColorStyle(props.success, props.error, pressed),
...props.badgeStyles,
]);

return (
<Wrapper
style={props.pressable ? wrapperStyles : wrapperStyles(false)}
onPress={props.onPress}
>
<Text
style={[styles.badgeText, textStyles]}
numberOfLines={1}
>
{props.text}
</Text>
</Wrapper>
);
};

Badge.displayName = 'Badge';
Badge.propTypes = propTypes;
Badge.defaultProps = defaultProps;
export default Badge;
18 changes: 6 additions & 12 deletions src/components/EnvironmentBadge.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,20 @@
import React from 'react';
import {View} from 'react-native';
import styles from '../styles/styles';
import CONST from '../CONST';
import Text from './Text';
import withEnvironment, {environmentPropTypes} from './withEnvironment';
import Badge from './Badge';

const EnvironmentBadge = (props) => {
// If we are on production, don't show any badge
if (props.environment === CONST.ENVIRONMENT.PRODUCTION) {
return null;
}

const backgroundColorStyle = props.environment === CONST.ENVIRONMENT.STAGING
? styles.badgeSuccess
: styles.badgeDanger;

return (
<View style={[styles.badge, backgroundColorStyle, styles.ml2]}>
<Text style={styles.badgeText}>
{props.environment}
</Text>
</View>
<Badge
success={props.environment === CONST.ENVIRONMENT.STAGING}
error={props.environment !== CONST.ENVIRONMENT.STAGING}
text={props.environment}
/>
);
};

Expand Down
32 changes: 11 additions & 21 deletions src/components/IOUBadge.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import React from 'react';
import PropTypes from 'prop-types';
import {Pressable} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import ONYXKEYS from '../ONYXKEYS';
import styles, {getBadgeColorStyle} from '../styles/styles';
import Navigation from '../libs/Navigation/Navigation';
import ROUTES from '../ROUTES';
import compose from '../libs/compose';
import withLocalize, {withLocalizePropTypes} from './withLocalize';
import CONST from '../CONST';
import Text from './Text';
import Badge from './Badge';

const propTypes = {
/** IOU Report data object */
Expand Down Expand Up @@ -53,24 +51,16 @@ const IOUBadge = (props) => {
Navigation.navigate(ROUTES.getIouDetailsRoute(props.iouReport.chatReportID, props.iouReport.reportID));
};
return (
<Pressable
style={({pressed}) => ([
styles.badge,
styles.ml2,
getBadgeColorStyle(props.session.email === props.iouReport.ownerEmail, pressed),
])}
>
<Text
style={styles.badgeText}
numberOfLines={1}
onPress={launchIOUDetailsModal}
>
{props.numberFormat(
props.iouReport.total / 100,
{style: 'currency', currency: props.iouReport.currency},
)}
</Text>
</Pressable>
<Badge
pressable
onPress={launchIOUDetailsModal}
success={props.session.email === props.iouReport.ownerEmail}
error={props.session.email !== props.iouReport.ownerEmail}
text={props.numberFormat(
props.iouReport.total / 100,
{style: 'currency', currency: props.iouReport.currency},
)}
/>
);
};

Expand Down
7 changes: 7 additions & 0 deletions src/components/MenuItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import styles, {getButtonBackgroundColorStyle, getIconFillColor} from '../styles
import Icon from './Icon';
import {ArrowRight} from './Icon/Expensicons';
import getButtonState from '../libs/getButtonState';
import Badge from './Badge';

const propTypes = {
/** Text to be shown as badge near the right end. */
badgeText: PropTypes.string,

/** Any additional styles to apply */
// eslint-disable-next-line react/forbid-prop-types
wrapperStyle: PropTypes.object,
Expand Down Expand Up @@ -58,6 +62,7 @@ const propTypes = {
};

const defaultProps = {
badgeText: undefined,
shouldShowRightIcon: false,
wrapperStyle: {},
success: false,
Expand All @@ -74,6 +79,7 @@ const defaultProps = {
};

const MenuItem = ({
badgeText,
onPress,
icon,
iconRight,
Expand Down Expand Up @@ -141,6 +147,7 @@ const MenuItem = ({
</View>
</View>
<View style={[styles.flexRow, styles.menuItemTextContainer]}>
{badgeText && <Badge text={badgeText} badgeStyles={[styles.alignSelfCenter]} />}
{subtitle && (
<View style={[styles.justifyContentCenter, styles.mr1]}>
<Text
Expand Down
21 changes: 21 additions & 0 deletions src/pages/settings/InitialPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ const propTypes = {
role: PropTypes.string,
})),

/** The user's wallet account */
userWallet: PropTypes.shape({
/** The user's current wallet balance */
availableBalance: PropTypes.number,
}),

...withLocalizePropTypes,
};

Expand All @@ -75,6 +81,9 @@ const defaultProps = {
network: {},
session: {},
policies: {},
userWallet: {
availableBalance: 0,
},
};

const defaultMenuItems = [
Expand Down Expand Up @@ -113,10 +122,17 @@ const defaultMenuItems = [
const InitialSettingsPage = ({
myPersonalDetails,
network,
numberFormat,
session,
policies,
translate,
userWallet,
}) => {
const walletBalance = numberFormat(
userWallet.availableBalance,
{style: 'currency', currency: 'USD'},
);

// On the very first sign in or after clearing storage these
// details will not be present on the first render so we'll just
// return nothing for now.
Expand Down Expand Up @@ -169,6 +185,7 @@ const InitialSettingsPage = ({
</View>
{_.map(menuItems, (item, index) => {
const keyTitle = item.translationKey ? translate(item.translationKey) : item.title;
const isPaymentItem = item.translationKey === 'common.payments';
return (
<MenuItem
key={`${keyTitle}_${index}`}
Expand All @@ -178,6 +195,7 @@ const InitialSettingsPage = ({
iconStyles={item.iconStyles}
iconFill={item.iconFill}
shouldShowRightIcon
badgeText={isPaymentItem ? walletBalance : undefined}
/>
);
})}
Expand Down Expand Up @@ -206,5 +224,8 @@ export default compose(
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
userWallet: {
key: ONYXKEYS.USER_WALLET,
},
}),
)(InitialSettingsPage);
20 changes: 12 additions & 8 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ const styles = {
},

badgeText: {
color: themeColors.textReversed,
color: themeColors.text,
fontSize: variables.fontSizeSmall,
lineHeight: 16,
...whiteSpace.noWrap,
Expand Down Expand Up @@ -2068,17 +2068,21 @@ function getBackgroundColorStyle(backgroundColor) {
}

/**
* Generate a style for the background color of the IOU badge
* Generate a style for the background color of the Badge
*
* @param {Boolean} isOwner
* @param {Boolean} [isPressed]
* @returns {Object}
* @param {Boolean} success
* @param {Boolean} error
* @param {boolean} [isPressed=false]
* @return {Object}
*/
function getBadgeColorStyle(isOwner, isPressed = false) {
if (isOwner) {
function getBadgeColorStyle(success, error, isPressed = false) {
if (success) {
return isPressed ? styles.badgeSuccessPressed : styles.badgeSuccess;
}
return isPressed ? styles.badgeDangerPressed : styles.badgeDanger;
if (error) {
return isPressed ? styles.badgeDangerPressed : styles.badgeDanger;
}
return {};
}

/**
Expand Down

0 comments on commit b08f80f

Please sign in to comment.