1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-01-05 20:46:14 +01:00
fab-manager/app/frontend/src/javascript/components/payment-schedule-summary.tsx

102 lines
3.8 KiB
TypeScript

/**
* This component displays a summary of the monthly payment schedule for the current cart, with a subscription
*/
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { react2angular } from 'react2angular';
import moment from 'moment';
import { IApplication } from '../models/application';
import '../lib/i18n';
import { PaymentSchedule } from '../models/payment-schedule';
import { Loader } from './loader';
import { FabModal } from './fab-modal';
import { IFablab } from '../models/fablab';
declare var Application: IApplication;
declare var Fablab: IFablab;
interface PaymentScheduleSummaryProps {
schedule: PaymentSchedule
}
const PaymentScheduleSummary: React.FC<PaymentScheduleSummaryProps> = ({ schedule }) => {
const { t } = useTranslation('shared');
const [modal, setModal] = useState(false);
/**
* Return the formatted localized date for the given date
*/
const formatDate = (date: Date): string => {
return Intl.DateTimeFormat().format(moment(date).toDate());
}
/**
* Return the formatted localized amount for the given price (eg. 20.5 => "20,50 €")
*/
const formatPrice = (price: number): string => {
return new Intl.NumberFormat(Fablab.intl_locale, {style: 'currency', currency: Fablab.intl_currency}).format(price);
}
/**
* Test if all payment deadlines have the same amount
*/
const hasEqualDeadlines = (): boolean => {
const prices = schedule.items.map(i => i.amount);
return prices.every(p => p === prices[0]);
}
/**
* Open or closes the modal dialog showing the full payment schedule
*/
const toggleFullScheduleModal = (): void => {
setModal(!modal);
}
return (
<div className="payment-schedule-summary">
<div>
<h4>{ t('app.shared.cart.your_payment_schedule') }</h4>
{hasEqualDeadlines() && <ul>
<li>
<span className="schedule-item-info">
{t('app.shared.cart.NUMBER_monthly_payment_of_AMOUNT', { NUMBER: schedule.items.length, AMOUNT: formatPrice(schedule.items[0].amount) })}
</span>
<span className="schedule-item-date">{t('app.shared.cart.first_debit')}</span>
</li>
</ul>}
{!hasEqualDeadlines() && <ul>
<li>
<span className="schedule-item-info">{t('app.shared.cart.monthly_payment_NUMBER', { NUMBER: 1 })}</span>
<span className="schedule-item-price">{formatPrice(schedule.items[0].amount)}</span>
<span className="schedule-item-date">{t('app.shared.cart.debit')}</span>
</li>
<li>
<span className="schedule-item-info">
{t('app.shared.cart.NUMBER_monthly_payment_of_AMOUNT', { NUMBER: schedule.items.length - 1, AMOUNT: formatPrice(schedule.items[1].amount) })}
</span>
</li>
</ul>}
<button className="view-full-schedule" onClick={toggleFullScheduleModal}>{t('app.shared.cart.view_full_schedule')}</button>
<FabModal title={t('app.shared.cart.your_payment_schedule')} isOpen={modal} toggleModal={toggleFullScheduleModal}>
<ul className="full-schedule">
{schedule.items.map(item => (
<li key={String(item.due_date)}>
<span className="schedule-item-date">{formatDate(item.due_date)}</span>
<span> </span>
<span className="schedule-item-price">{formatPrice(item.amount)}</span>
</li>
))}
</ul>
</FabModal>
</div>
</div>
);
}
const PaymentScheduleSummaryWrapper: React.FC<PaymentScheduleSummaryProps> = ({ schedule }) => {
return (
<Loader>
<PaymentScheduleSummary schedule={schedule} />
</Loader>
);
}
Application.Components.component('paymentScheduleSummary', react2angular(PaymentScheduleSummaryWrapper, ['schedule']));