2020-11-18 16:01:05 +01:00
|
|
|
/**
|
|
|
|
* This component displays a summary of the amount paid with the virtual wallet, for the current transaction
|
|
|
|
*/
|
|
|
|
|
2020-11-25 17:13:45 +01:00
|
|
|
import React, { useState, useEffect } from 'react';
|
2020-11-18 16:01:05 +01:00
|
|
|
import { useTranslation } from 'react-i18next';
|
|
|
|
import { react2angular } from 'react2angular';
|
|
|
|
import { IApplication } from '../models/application';
|
|
|
|
import '../lib/i18n';
|
|
|
|
import { Loader } from './loader';
|
|
|
|
import { User } from '../models/user';
|
|
|
|
import { Wallet } from '../models/wallet';
|
2020-11-24 13:26:15 +01:00
|
|
|
import { IFablab } from '../models/fablab';
|
2020-11-25 17:13:45 +01:00
|
|
|
import WalletLib from '../lib/wallet';
|
2020-12-29 17:31:57 +01:00
|
|
|
import { CartItems } from '../models/payment';
|
|
|
|
import { Reservation } from '../models/reservation';
|
|
|
|
import { SubscriptionRequest } from '../models/subscription';
|
2020-11-18 16:01:05 +01:00
|
|
|
|
|
|
|
declare var Application: IApplication;
|
2020-11-24 13:26:15 +01:00
|
|
|
declare var Fablab: IFablab;
|
2020-11-18 16:01:05 +01:00
|
|
|
|
|
|
|
interface WalletInfoProps {
|
2020-12-29 17:31:57 +01:00
|
|
|
cartItems: CartItems,
|
2020-11-24 13:26:15 +01:00
|
|
|
currentUser: User,
|
|
|
|
wallet: Wallet,
|
|
|
|
price: number,
|
2020-11-18 16:01:05 +01:00
|
|
|
}
|
|
|
|
|
2020-12-29 17:31:57 +01:00
|
|
|
export const WalletInfo: React.FC<WalletInfoProps> = ({ cartItems, currentUser, wallet, price }) => {
|
2020-11-25 17:13:45 +01:00
|
|
|
const { t } = useTranslation('shared');
|
|
|
|
const [remainingPrice, setRemainingPrice] = useState(0);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Refresh the remaining price on each display
|
|
|
|
*/
|
|
|
|
useEffect(() => {
|
|
|
|
const wLib = new WalletLib(wallet);
|
|
|
|
setRemainingPrice(wLib.computeRemainingPrice(price));
|
2020-12-29 17:31:57 +01:00
|
|
|
});
|
2020-11-18 16:01:05 +01:00
|
|
|
|
2020-11-24 13:26:15 +01:00
|
|
|
/**
|
2020-12-29 17:31:57 +01:00
|
|
|
* Return the formatted localized amount for the given price (e.g. 20.5 => "20,50 €")
|
2020-11-24 13:26:15 +01:00
|
|
|
*/
|
|
|
|
const formatPrice = (price: number): string => {
|
|
|
|
return new Intl.NumberFormat(Fablab.intl_locale, {style: 'currency', currency: Fablab.intl_currency}).format(price);
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Check if the currently connected used is also the person making the reservation.
|
2020-12-29 17:31:57 +01:00
|
|
|
* If the currently connected user (i.e. the operator), is an admin or a manager, he may book the reservation for someone else.
|
2020-11-24 13:26:15 +01:00
|
|
|
*/
|
|
|
|
const isOperatorAndClient = (): boolean => {
|
2020-12-29 17:31:57 +01:00
|
|
|
return currentUser.id == buyingItem().user_id;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Return the item currently bought (reservation or subscription)
|
|
|
|
*/
|
|
|
|
const buyingItem = (): Reservation|SubscriptionRequest => {
|
|
|
|
return cartItems.reservation || cartItems.subscription;
|
2020-11-24 13:26:15 +01:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* If the client has some money in his wallet & the price is not zero, then we should display this component.
|
|
|
|
*/
|
|
|
|
const shouldBeShown = (): boolean => {
|
|
|
|
return wallet.amount > 0 && price > 0;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* If the amount in the wallet is not enough to cover the whole price, then the user must pay the remaining price
|
|
|
|
* using another payment mean.
|
|
|
|
*/
|
|
|
|
const hasRemainingPrice = (): boolean => {
|
|
|
|
return remainingPrice > 0;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Does the current cart contains a payment schedule?
|
|
|
|
*/
|
|
|
|
const isPaymentSchedule = (): boolean => {
|
2020-12-29 17:31:57 +01:00
|
|
|
return buyingItem().plan_id && buyingItem().payment_schedule;
|
2020-11-24 13:26:15 +01:00
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Return the human-readable name of the item currently bought with the wallet
|
|
|
|
*/
|
|
|
|
const getPriceItem = (): string => {
|
|
|
|
let item = 'other';
|
2020-12-29 17:31:57 +01:00
|
|
|
if (cartItems.reservation) {
|
2020-11-24 13:26:15 +01:00
|
|
|
item = 'reservation';
|
2020-12-29 17:31:57 +01:00
|
|
|
} else if (cartItems.subscription) {
|
|
|
|
if (cartItems.subscription.payment_schedule) {
|
2020-11-24 13:26:15 +01:00
|
|
|
item = 'first_deadline';
|
|
|
|
} else item = 'subscription';
|
2020-11-18 16:01:05 +01:00
|
|
|
}
|
|
|
|
|
2020-11-24 13:26:15 +01:00
|
|
|
return t(`app.shared.wallet.wallet_info.item_${item}`);
|
|
|
|
}
|
2020-11-18 16:01:05 +01:00
|
|
|
|
2020-11-24 13:26:15 +01:00
|
|
|
return (
|
|
|
|
<div className="wallet-info">
|
|
|
|
{shouldBeShown() && <div>
|
|
|
|
{isOperatorAndClient() && <div>
|
|
|
|
<h3>{t('app.shared.wallet.wallet_info.you_have_AMOUNT_in_wallet', {AMOUNT: formatPrice(wallet.amount)})}</h3>
|
|
|
|
{!hasRemainingPrice() && <p>
|
|
|
|
{t('app.shared.wallet.wallet_info.wallet_pay_ITEM', {ITEM: getPriceItem()})}
|
|
|
|
</p>}
|
|
|
|
{hasRemainingPrice() && <p>
|
|
|
|
{t('app.shared.wallet.wallet_info.credit_AMOUNT_for_pay_ITEM', {
|
|
|
|
AMOUNT: formatPrice(remainingPrice),
|
|
|
|
ITEM: getPriceItem()
|
|
|
|
})}
|
|
|
|
</p>}
|
|
|
|
</div>}
|
|
|
|
{!isOperatorAndClient() && <div>
|
|
|
|
<h3>{t('app.shared.wallet.wallet_info.client_have_AMOUNT_in_wallet', {AMOUNT: formatPrice(wallet.amount)})}</h3>
|
|
|
|
{!hasRemainingPrice() && <p>
|
|
|
|
{t('app.shared.wallet.wallet_info.client_wallet_pay_ITEM', {ITEM: getPriceItem()})}
|
|
|
|
</p>}
|
|
|
|
{hasRemainingPrice() && <p>
|
|
|
|
{t('app.shared.wallet.wallet_info.client_credit_AMOUNT_for_pay_ITEM', {
|
|
|
|
AMOUNT: formatPrice(remainingPrice),
|
|
|
|
ITEM: getPriceItem()
|
|
|
|
})}
|
|
|
|
</p>}
|
|
|
|
</div>}
|
|
|
|
{!hasRemainingPrice() && isPaymentSchedule() && <p className="info-deadlines">
|
|
|
|
<i className="fa fa-warning"/>
|
|
|
|
<span>{t('app.shared.wallet.wallet_info.other_deadlines_no_wallet')}</span>
|
|
|
|
</p>}
|
|
|
|
</div>}
|
|
|
|
</div>
|
|
|
|
);
|
2020-11-18 16:01:05 +01:00
|
|
|
}
|
|
|
|
|
2020-12-29 17:31:57 +01:00
|
|
|
const WalletInfoWrapper: React.FC<WalletInfoProps> = ({ currentUser, cartItems, price, wallet }) => {
|
2020-11-24 13:26:15 +01:00
|
|
|
return (
|
|
|
|
<Loader>
|
2020-12-29 17:31:57 +01:00
|
|
|
<WalletInfo currentUser={currentUser} cartItems={cartItems} price={price} wallet={wallet}/>
|
2020-11-24 13:26:15 +01:00
|
|
|
</Loader>
|
|
|
|
);
|
2020-11-18 16:01:05 +01:00
|
|
|
}
|
|
|
|
|
2020-12-29 17:31:57 +01:00
|
|
|
Application.Components.component('walletInfo', react2angular(WalletInfoWrapper, ['currentUser', 'price', 'cartItems', 'wallet']));
|