import React, { useEffect, useState } from 'react'; import _ from 'lodash'; import { Machine } from '../../models/machine'; import { User } from '../../models/user'; import { UserPack } from '../../models/user-pack'; import UserPackAPI from '../../api/user-pack'; import SettingAPI from '../../api/setting'; import { SettingName } from '../../models/setting'; import { FabButton } from '../base/fab-button'; import { useTranslation } from 'react-i18next'; import { ProposePacksModal } from './propose-packs-modal'; import { Loader } from '../base/loader'; import { react2angular } from 'react2angular'; import { IApplication } from '../../models/application'; declare var Application: IApplication; type PackableItem = Machine; interface PacksSummaryProps { item: PackableItem, itemType: 'Machine', customer?: User, operator: User, onError: (message: string) => void, onSuccess: (message: string) => void, refresh?: Promise } const PacksSummaryComponent: React.FC = ({ item, itemType, customer, operator, onError, onSuccess, refresh }) => { const { t } = useTranslation('logged'); const [userPacks, setUserPacks] = useState>(null); const [threshold, setThreshold] = useState(null); const [packsModal, setPacksModal] = useState(false); useEffect(() => { SettingAPI.get(SettingName.RenewPackThreshold) .then(data => setThreshold(parseFloat(data.value))) .catch(error => onError(error)); }, []); useEffect(() => { if (_.isEmpty(customer)) return; getUserPacksData(); }, [item, itemType, customer]); useEffect(() => { if (refresh instanceof Promise) { refresh.then(getUserPacksData); } }, [refresh]); /** * Fetch the user packs data from the API */ const getUserPacksData = (): void => { UserPackAPI.index({ user_id: customer.id, priceable_type: itemType, priceable_id: item.id }) .then(data => setUserPacks(data)) .catch(error => onError(error)); } /** * Total of minutes used by the customer */ const totalUsed = (): number => { if (!userPacks) return 0; return userPacks.map(up => up.minutes_used).reduce((acc, curr) => acc + curr, 0); } /** * Total of minutes available is the packs bought by the customer */ const totalAvailable = (): number => { if (!userPacks) return 0; return userPacks.map(up => up.prepaid_pack.minutes).reduce((acc, curr) => acc + curr, 0); } /** * Total prepaid hours remaining for the current customer */ const totalHours = (): number => { return (totalAvailable() - totalUsed()) / 60; } /** * Do we need to display the "buy new pack" button? */ const shouldDisplayButton = (): boolean => { if (threshold < 1) { return totalAvailable() - totalUsed() <= totalAvailable() * threshold; } return totalAvailable() - totalUsed() <= threshold * 60; } /** * Open/closes the prepaid-pack buying modal */ const togglePacksModal = (): void => { setPacksModal(!packsModal); } /** * Callback triggered when the customer has successfully bought a prepaid-pack */ const handlePackBoughtSuccess = (message: string): void => { onSuccess(message); togglePacksModal(); UserPackAPI.index({ user_id: customer.id, priceable_type: itemType, priceable_id: item.id }) .then(data => setUserPacks(data)) .catch(error => onError(error)); } // prevent component rendering if no customer selected if (_.isEmpty(customer)) return
; return (

{t('app.logged.packs_summary.prepaid_hours')}

{totalHours() > 0 && t('app.logged.packs_summary.remaining_HOURS', { HOURS: totalHours(), ITEM: itemType })} {totalHours() === 0 && t('app.logged.packs_summary.no_hours', { ITEM: itemType })} {shouldDisplayButton() &&
}> {t('app.logged.packs_summary.buy_a_new_pack')}
}
); } export const PacksSummary: React.FC = ({ item, itemType, customer, operator, onError, onSuccess, refresh }) => { return ( ); } Application.Components.component('packsSummary', react2angular(PacksSummary, ['item', 'itemType', 'customer', 'operator', 'onError', 'onSuccess', 'refresh']));