Commit 158a16f7 authored by Benjamin Bouvier's avatar Benjamin Bouvier
Browse files

Cleanup: make the AmountWell a stateless UI component;

parent 6a05ae29
import React from 'react';
import { translate as $t } from '../../helpers';
export class AmountWell extends React.Component {
constructor(props) {
// this.props = {
// backgroundColor,
// title,
// subtitle,
// operations,
// initialAmount,
// filterFunction
// }
super(props);
}
computeTotal(operations) {
let total = operations
.filter(this.props.filterFunction)
.reduce((a, b) => a + b.amount, this.props.initialAmount);
return Math.round(total * 100) / 100;
}
getTotal() {
return this.computeTotal(this.props.operations);
}
render() {
let style = `well ${this.props.backgroundColor}`;
return (
<div className={ this.props.size }>
<div className={ style }>
<span className="well-icon">
<i className={ `fa fa-${this.props.icon}` }></i>
</span>
<span className="operation-amount">
{ this.props.formatCurrency(this.getTotal()) }
</span><br/>
<span className="well-title">{ this.props.title }</span><br/>
<span className="well-sub">{ this.props.subtitle }</span>
</div>
</div>
);
}
}
export class FilteredAmountWell extends AmountWell {
render() {
let style = `well ${this.props.backgroundColor}`;
let sub = this.props.hasFilteredOperations ?
$t('client.amount_well.current_search') :
$t('client.amount_well.this_month');
return (
<div className={ this.props.size }>
<div className={ style }>
<span className="well-icon">
<i className={ `fa fa-${this.props.icon}` }></i>
</span>
<span className="operation-amount">
{ this.props.formatCurrency(this.getTotal()) }
</span><br/>
<span className="well-title">{ this.props.title }</span><br/>
<span className="well-sub">{ sub }</span>
</div>
import { assertHas } from '../../helpers';
export default props => {
assertHas(props, 'backgroundColor');
assertHas(props, 'size');
assertHas(props, 'icon');
assertHas(props, 'title');
assertHas(props, 'subtitle');
assertHas(props, 'content');
let style = `well ${props.backgroundColor}`;
return (
<div className={ props.size }>
<div className={ style }>
<span className="well-icon">
<i className={ `fa fa-${props.icon}` }></i>
</span>
<span className="operation-amount">
{ props.content }
</span><br/>
<span className="well-title">{ props.title }</span><br/>
<span className="well-sub">{ props.subtitle }</span>
</div>
);
}
}
</div>
);
};
......@@ -8,7 +8,7 @@ import { translate as $t } from '../../helpers';
import { get } from '../../store';
import { AmountWell, FilteredAmountWell } from './amount-well';
import AmountWell from './amount-well';
import SearchComponent from './search';
import OperationItem from './item';
import SyncButton from './sync-button';
......@@ -22,17 +22,6 @@ function computeOperationHeight() {
return window.innerWidth < 768 ? 41 : 54;
}
// Filter functions used in amount wells.
function noFilter() {
return true;
}
function isPositive(op) {
return op.amount > 0;
}
function isNegative(op) {
return op.amount < 0;
}
function filterOperationsThisMonth(operations) {
let now = new Date();
return operations.filter(op => {
......@@ -41,6 +30,13 @@ function filterOperationsThisMonth(operations) {
});
}
function computeTotal(format, filterFunction, operations, initial = 0) {
let total = operations
.filter(filterFunction)
.reduce((a, b) => a + b.amount, initial);
return format(Math.round(total * 100) / 100);
}
class OperationsComponent extends React.Component {
constructor(props) {
......@@ -98,76 +94,68 @@ class OperationsComponent extends React.Component {
// End of implementation of infinite list.
render() {
// Edge case: the component hasn't retrieved the account yet.
if (this.props.account === null) {
return <div/>;
}
let asOf = $t('client.operations.as_of');
let lastCheckedDate = new Date(this.props.account.lastChecked).toLocaleDateString();
let lastCheckDate = `${asOf} ${lastCheckedDate}`;
let wellOperations;
// TODO cleanup: this component should set all fields of the
// AmountWell, so we can make the AmountWell a dump component.
let wellOperations, filteredSub;
if (this.props.hasSearchFields) {
wellOperations = this.props.filteredOperations;
filteredSub = $t('client.amount_well.current_search');
} else {
wellOperations = filterOperationsThisMonth(this.props.operations);
filteredSub = $t('client.amount_well.this_month');
}
let formatCurrency = this.props.account.formatCurrency;
let format = this.props.account.formatCurrency;
let balance = computeTotal(format,
() => true,
this.props.operations,
this.props.account.initialAmount);
let positiveSum = computeTotal(format, x => x.amount > 0, wellOperations, 0);
let negativeSum = computeTotal(format, x => x.amount < 0, wellOperations, 0);
let sum = computeTotal(format, () => true, wellOperations, 0);
return (
<div>
<div className="row operation-wells" ref="wells">
<AmountWell
size="col-xs-12 col-md-3"
backgroundColor="background-lightblue"
size="col-xs-12 col-md-3"
icon="balance-scale"
title={ $t('client.operations.current_balance') }
subtitle={ lastCheckDate }
operations={ this.props.operations }
initialAmount={ this.props.account.initialAmount }
filterFunction={ noFilter }
formatCurrency={ formatCurrency }
content={ balance }
/>
<FilteredAmountWell
size="col-xs-12 col-md-3"
<AmountWell
backgroundColor="background-green"
size="col-xs-12 col-md-3"
icon="arrow-down"
title={ $t('client.operations.received') }
operations={ wellOperations }
hasFilteredOperations={ this.props.hasSearchFields }
initialAmount={ 0 }
filterFunction={ isPositive }
formatCurrency={ formatCurrency }
subtitle={ filteredSub }
content={ positiveSum }
/>
<FilteredAmountWell
size="col-xs-12 col-md-3"
<AmountWell
backgroundColor="background-orange"
size="col-xs-12 col-md-3"
icon="arrow-up"
title={ $t('client.operations.spent') }
operations={ wellOperations }
hasFilteredOperations={ this.props.hasSearchFields }
initialAmount={ 0 }
filterFunction={ isNegative }
formatCurrency={ formatCurrency }
subtitle={ filteredSub }
content={ negativeSum }
/>
<FilteredAmountWell
<AmountWell
size="col-xs-12 col-md-3"
backgroundColor="background-darkblue"
icon="database"
title={ $t('client.operations.saved') }
operations={ wellOperations }
hasFilteredOperations={ this.props.hasSearchFields }
initialAmount={ 0 }
filterFunction={ noFilter }
formatCurrency={ formatCurrency }
subtitle={ filteredSub }
content={ sum }
/>
</div>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment