Skip to content

Commit

Permalink
Pay with Business accounts (#797)
Browse files Browse the repository at this point in the history
* start business accounts ui payment methods

* wip

* wip service estimation adapt

* fix

* add skelton. fix service estimation interval. hide business payment methods in default payment select

* show business tab only if at least 1 buiz payment method

* display BA name in ride history and active

* add name of BA to future ride

* checkmark to the right

* style fix

* add mixpanels

* update BA svg, add subtitle to BA payment card

* add subtitle

* clean business account state

* Update styled.js

* Update index.tsx

* extract to styled files @ormiz

* on submit AUT-18223 fix

* fix AUT-18227

* Update index.tsx

* add empty state for services and choose payment

* always allow offline for BA

* new logic of storing last BA

* fixes

* tabs not scrollable

* Update index.tsx

* remove Montserrat

* Update index.tsx

* Revert "remove Montserrat"

This reverts commit 2769430.

* inter

* remove reason from business pay

* fix chosen method

* fix add payment , rm BA id

* fix for delete from BA

* Update index.tsx

* fix active tab

* cr

* cr2

* cr them context

* CR styled

* fix flex

* fix div width of payment metod title
  • Loading branch information
OmerGery authored Jan 28, 2024
1 parent 4945961 commit 204c7b1
Show file tree
Hide file tree
Showing 30 changed files with 644 additions and 126 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const ActiveRideContent = () => {
ride={ride}
/>
<RidePaymentDetails
rideId={ride.id || ''}
ride={ride}
paymentMethod={ride.payment?.paymentMethod}
state={ride.state}
currency={ride.priceCurrency}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';
import { BoldTitle, SubTitle, TitleWithSubTitle } from './styled';

interface BusinessAccountTextProps {
title: string;
subTitle: string;
}
const BusinessAccountText = ({
title, subTitle,
} : BusinessAccountTextProps) => (
<TitleWithSubTitle>
<BoldTitle numberOfLines={1}>{title}</BoldTitle>
<SubTitle numberOfLines={1}>{subTitle}</SubTitle>
</TitleWithSubTitle>
);

export default BusinessAccountText;
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Text, View } from 'react-native';
import styled from 'styled-components';
import { FONT_SIZES, FONT_WEIGHTS } from '../../context/theme';

export const TitleWithSubTitle = styled(View)`
display: flex;
flex-direction: column;
flex: 1 0 0;
`;
export const BaseText = styled(Text)`
color: #212229;
${FONT_SIZES.LARGE};
font-family: Inter;
font-style: normal;
line-height: 20px;
`;
export const SubTitle = styled(BaseText)`
font-weight: 500;
`;
export const BoldTitle = styled(BaseText)`
font-weight: 700;
`;
66 changes: 52 additions & 14 deletions examples/client/Locomotion/src/Components/CardRow/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { View, Text } from 'react-native';
import moment from 'moment';
import styled, { ThemeContext } from 'styled-components';
import { PaymentIcon } from 'react-native-payment-icons';
import BusinessAccountText from '../BusinessAccountText';
import { RideInterface, RidePageContext } from '../../context/newRideContext';
import { PAYMENT_METHODS, paymentMethodToIconMap } from '../../pages/Payments/consts';
import Button from '../Button';
import { capitalizeFirstLetter, getLastFourForamttedShort } from '../../pages/Payments/cardDetailUtils';
Expand All @@ -13,7 +15,7 @@ import SvgIcon from '../SvgIcon';
import selected from '../../assets/selected-v.svg';
import { Start, StartCapital } from '../../lib/text-direction';
import chevronIcon from '../../assets/chevron.svg';
import { isCashPaymentMethod } from '../../lib/ride/utils';
import { isCashPaymentMethod, isOfflinePaymentMethod } from '../../lib/ride/utils';
import paymentContext from '../../context/payments';

type ContainerProps = {
Expand Down Expand Up @@ -93,9 +95,28 @@ const style = {

const CardRow = (paymentMethod: any) => {
const { primaryColor } = useContext(ThemeContext);
const { offlinePaymentText, loadOfflinePaymentText } = paymentContext.useContainer();
const {
offlinePaymentText,
loadOfflinePaymentText,
getBusinessAccountNameById,
} = paymentContext.useContainer();
const { businessAccountId } = paymentMethod;
const [isCardExpired, setIsCardExpired] = useState(false);

const getPaymentMethodTitle = () => {
const businessAccountName = getBusinessAccountNameById(businessAccountId);
if (businessAccountName) {
return businessAccountName;
}
if (isCashPaymentMethod(paymentMethod)) {
return i18n.t('payments.cash');
}
if (isOfflinePaymentMethod(paymentMethod)) {
return offlinePaymentText;
}
return capitalizeFirstLetter(paymentMethod.name);
};

useEffect(() => {
loadOfflinePaymentText();
}, []);
Expand All @@ -111,11 +132,15 @@ const CardRow = (paymentMethod: any) => {
: (`${paymentMethod.testIdPrefix || ''}ChoosePaymentMethod${paymentMethod.id === PAYMENT_METHODS.OFFLINE || paymentMethod.id === PAYMENT_METHODS.CASH ? `_${paymentMethod.id}` : ''}`);

const getPaymentMethodIcon = () => {
if (paymentMethod.noSvg) {
return null;
}
const { brand, id, lastFour } = paymentMethod;
const isCard = lastFour;
if (isCard) {
return <PaymentIcon type={brand} />;
}
if (!paymentMethodToIconMap[id]) { return null; }
return (
<SvgIcon
fill={primaryColor}
Expand Down Expand Up @@ -154,7 +179,7 @@ const CardRow = (paymentMethod: any) => {
: (
<>
{getPaymentMethodIcon()}
{paymentMethod.mark ? (
{(paymentMethod.mark && !paymentMethod.alignMarkToRight) ? (
<SvgIcon
style={{
position: 'absolute',
Expand All @@ -179,17 +204,19 @@ const CardRow = (paymentMethod: any) => {
)
: (
<>
{!paymentMethod.lastFour
? (
<Type>
{isCashPaymentMethod(paymentMethod) ? i18n.t('payments.cash') : offlinePaymentText }
</Type>
)
: (
<Type>
{capitalizeFirstLetter(paymentMethod.name)}
</Type>
)}
{
(businessAccountId && offlinePaymentText)
? (
<BusinessAccountText
title={getPaymentMethodTitle()}
subTitle={offlinePaymentText}
/>
)
: (
<Type>
{getPaymentMethodTitle()}
</Type>
)}
{paymentMethod.lastFour
? <Description>{getLastFourForamttedShort(paymentMethod.lastFour)}</Description>
: null}
Expand All @@ -205,6 +232,17 @@ const CardRow = (paymentMethod: any) => {
{paymentMethod.disabledReason}
</Description>
)}
{(paymentMethod.mark && paymentMethod.alignMarkToRight) ? (
<SvgIcon
style={{
position: 'absolute',
right: 10,
bottom: 15,
}}
Svg={selected}
fill={primaryColor}
/>
) : null }
</Container>
</Button>
</>
Expand Down
26 changes: 26 additions & 0 deletions examples/client/Locomotion/src/Components/EmptyState/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import {
Container, Description, Title, TitleWithoutDescription,
} from './styled';

interface EmptyStateProps {
title: string;
description?: string;
}
const EmptyState = ({
title,
description,
}: EmptyStateProps) => (
<Container>
{description
? <Title>{title}</Title>
: <TitleWithoutDescription>{title}</TitleWithoutDescription>
}

{description ? <Description>{description}</Description> : null}
</Container>
);
EmptyState.defaultProps = {
description: '',
};
export default EmptyState;
40 changes: 40 additions & 0 deletions examples/client/Locomotion/src/Components/EmptyState/styled.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Text, View } from 'react-native';
import styled from 'styled-components';
import { FONT_SIZES, FONT_WEIGHTS } from '../../context/theme';

export const Container = styled(View)`
border-radius: 8px;
border: 1px dashed rgba(125, 139, 172, 0.32);
display: flex;
padding: 16px;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 4px;
flex: 1 0 0;
align-self: stretch;
`;
export const Title = styled(Text)`
align-self: stretch;
color: #212229;
text-align: center;
${FONT_WEIGHTS.REGULAR};
${FONT_SIZES.LARGE};
font-weight: 600;
`;
export const Description = styled(Text)`
align-self: stretch;
color: #666975;
text-align: center;
${FONT_WEIGHTS.REGULAR};
${FONT_SIZES.LARGE};
font-weight: 400;
`;
export const TitleWithoutDescription = styled(Text)`
align-self: stretch;
color: #666975;
text-align: center;
${FONT_WEIGHTS.REGULAR};
${FONT_SIZES.LARGE};
font-weight: 500;
`;
24 changes: 20 additions & 4 deletions examples/client/Locomotion/src/Components/RideCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import StopPointsVerticalView from '../StopPointsVerticalView';
import { getFormattedPrice, isPriceEstimated, convertTimezoneByLocation } from '../../context/newRideContext/utils';
import cashIcon from '../../assets/cash.svg';
import offlineIcon from '../../assets/offline.svg';
import { PAYMENT_METHODS } from '../../pages/Payments/consts';
import PaymentContext from '../../context/payments';
import SettingsContext from '../../context/settings';
Expand All @@ -23,17 +24,26 @@ interface CardComponentProps {
brand: any;
id: string;
}
businessAccountId: string | undefined;
}
const CardComponent = ({ paymentMethod }: CardComponentProps) => {
const CardComponent = ({ paymentMethod, businessAccountId }: CardComponentProps) => {
const isCash = PAYMENT_METHODS.CASH === paymentMethod.id;
const isOffline = PAYMENT_METHODS.OFFLINE === paymentMethod.id;
const { offlinePaymentText, loadOfflinePaymentText } = PaymentContext.useContainer();
const {
offlinePaymentText,
loadOfflinePaymentText,
getBusinessAccountNameById,
} = PaymentContext.useContainer();

useEffect(() => {
loadOfflinePaymentText();
}, []);

const getText = () => {
const businessAccountName = getBusinessAccountNameById(businessAccountId);
if (businessAccountName) {
return businessAccountName;
}
if (isCash) {
return i18n.t('payments.cash');
} if (isOffline) {
Expand All @@ -47,12 +57,13 @@ const CardComponent = ({ paymentMethod }: CardComponentProps) => {
return cashIcon;
}
if (isOffline) {
return null;
return offlineIcon;
}
};
return (
<TextRowWithIcon
text={getText() || ''}
subTitle={businessAccountId ? offlinePaymentText : ''}
Image={() => !isCash && !isOffline && <PaymentIcon type={paymentMethod.brand} />}
icon={getIcon()}
style={{ marginTop: 10, marginBottom: 10 }}
Expand Down Expand Up @@ -168,7 +179,12 @@ const RideCard = ({
</DateContainer>

<StopPointsVerticalView ride={ride} />
{paymentMethod && <CardComponent paymentMethod={paymentMethod} />}
{paymentMethod && (
<CardComponent
paymentMethod={paymentMethod}
businessAccountId={ride.businessAccountId}
/>
)}
<RoundedButton testID="cancelRide" onPress={onPress} hollow type="cancel">
{i18n.t('home.cancelRideButton')}
</RoundedButton>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { getFormattedPrice } from '../../context/newRideContext/utils';
import CardRow from '../CardRow';
import CardsTitle from '../CardsTitle';
import i18n from '../../I18n';
import { PriceCalculation, RidePageContext } from '../../context/newRideContext';
import { PriceCalculation, RideInterface, RidePageContext } from '../../context/newRideContext';
import {
PaymentRow, RidePriceDetails, PriceText, ViewDetails, CardRowContainer,
} from './styled';
Expand All @@ -16,12 +16,12 @@ import * as navigationService from '../../services/navigation';
import Button from '../Button';

const RidePaymentDetails = ({
rideId,
ride,
paymentMethod,
rideHistory = false,
state,
} :{
rideId: string,
ride: RideInterface,
paymentMethod: PaymentMethodInterface,
rideHistory: boolean
currency: string,
Expand All @@ -36,7 +36,7 @@ const RidePaymentDetails = ({
const { showPrice, loadShowPrice } = SettingsContext.useContainer();

const updatePriceCalculation = async () => {
const calculation = await getRidePriceCalculation(rideId);
const calculation = await getRidePriceCalculation(ride?.id);
setPriceCalculation(calculation);
};

Expand All @@ -53,7 +53,7 @@ const RidePaymentDetails = ({
<CardsTitle noPaddingLeft title={i18n.t('ride.paymentMethod')} />
<PaymentRow>
<CardRowContainer>
<CardRow {...paymentMethod} />
<CardRow {...{ ...paymentMethod, businessAccountId: ride.businessAccountId }} />
</CardRowContainer>
<RidePriceDetails>

Expand All @@ -74,7 +74,7 @@ const RidePaymentDetails = ({
testID="viewRidePaymentDetails"
noBackground
onPress={() => navigationService.navigate(MAIN_ROUTES.RIDE_PRICE_BREAKDOWN,
{ rideId, rideHistory })}
{ rideId: ride.id, rideHistory })}
>
{state !== RIDE_STATES.CANCELED
|| (state === RIDE_STATES.CANCELED
Expand Down
Loading

0 comments on commit 204c7b1

Please sign in to comment.