diff options
author | jloup <jean-loup.jamet@trainline.com> | 2018-07-19 18:00:20 +0200 |
---|---|---|
committer | jloup <jean-loup.jamet@trainline.com> | 2018-07-19 18:00:20 +0200 |
commit | 1fcb77583201f9979a839fcae2dd642edc25af96 (patch) | |
tree | 778f6aca2612fc277c612dcb748cacf2e0d975ac | |
parent | 574bf1e47f1b611449faa8fa5848ba63dfc7d0e9 (diff) | |
download | Front-1fcb77583201f9979a839fcae2dd642edc25af96.tar.gz Front-1fcb77583201f9979a839fcae2dd642edc25af96.tar.zst Front-1fcb77583201f9979a839fcae2dd642edc25af96.zip |
Display total balance/performance.v0.0.24
-rw-r--r-- | api/admin.go | 16 | ||||
-rw-r--r-- | cmd/web/js/admin.jsx | 21 | ||||
-rw-r--r-- | cmd/web/js/balance.jsx | 19 |
3 files changed, 43 insertions, 13 deletions
diff --git a/api/admin.go b/api/admin.go index 3b16d87..e4bfda5 100644 --- a/api/admin.go +++ b/api/admin.go | |||
@@ -4,13 +4,18 @@ import ( | |||
4 | "fmt" | 4 | "fmt" |
5 | 5 | ||
6 | "git.immae.eu/Cryptoportfolio/Front.git/db" | 6 | "git.immae.eu/Cryptoportfolio/Front.git/db" |
7 | "github.com/shopspring/decimal" | ||
7 | ) | 8 | ) |
8 | 9 | ||
9 | type GetAllPortfoliosQuery struct { | 10 | type GetAllPortfoliosQuery struct { |
10 | In struct { | 11 | In struct { |
11 | Market string | 12 | Market string |
12 | } | 13 | } |
13 | Out map[string]Portfolio | 14 | Out struct { |
15 | Portfolios map[string]Portfolio `json:"portfolios"` | ||
16 | TotalBTCValue decimal.Decimal `json:"totalBtcValue"` | ||
17 | TotalBTCVariation decimal.Decimal `json:"totalBtcVariation"` | ||
18 | } | ||
14 | } | 19 | } |
15 | 20 | ||
16 | func (q GetAllPortfoliosQuery) ValidateParams() *Error { | 21 | func (q GetAllPortfoliosQuery) ValidateParams() *Error { |
@@ -27,7 +32,7 @@ func (q GetAllPortfoliosQuery) Run() (interface{}, *Error) { | |||
27 | return nil, NewInternalError(err) | 32 | return nil, NewInternalError(err) |
28 | } | 33 | } |
29 | 34 | ||
30 | q.Out = make(map[string]Portfolio) | 35 | q.Out.Portfolios = make(map[string]Portfolio) |
31 | 36 | ||
32 | for _, marketConfig := range u { | 37 | for _, marketConfig := range u { |
33 | report, err := GetWeekPortfolio(marketConfig) | 38 | report, err := GetWeekPortfolio(marketConfig) |
@@ -39,8 +44,13 @@ func (q GetAllPortfoliosQuery) Run() (interface{}, *Error) { | |||
39 | return nil, NewInternalError(err) | 44 | return nil, NewInternalError(err) |
40 | } | 45 | } |
41 | 46 | ||
42 | q.Out[marketConfig.User.Email] = report.Round() | 47 | q.Out.Portfolios[marketConfig.User.Email] = report.Round() |
48 | q.Out.TotalBTCValue = q.Out.TotalBTCValue.Add(report.Performance.Value) | ||
49 | q.Out.TotalBTCVariation = q.Out.TotalBTCVariation.Add(report.Performance.Variation) | ||
43 | } | 50 | } |
44 | 51 | ||
52 | q.Out.TotalBTCValue = q.Out.TotalBTCValue.Round(3) | ||
53 | q.Out.TotalBTCVariation = q.Out.TotalBTCVariation.Round(3) | ||
54 | |||
45 | return q.Out, nil | 55 | return q.Out, nil |
46 | } | 56 | } |
diff --git a/cmd/web/js/admin.jsx b/cmd/web/js/admin.jsx index 81ce15d..19eb3ef 100644 --- a/cmd/web/js/admin.jsx +++ b/cmd/web/js/admin.jsx | |||
@@ -6,7 +6,7 @@ import Panel from './panel.js'; | |||
6 | class AdminDashboard extends React.Component { | 6 | class AdminDashboard extends React.Component { |
7 | constructor(state) { | 7 | constructor(state) { |
8 | super(state); | 8 | super(state); |
9 | this.state = {'portfolios': null}; | 9 | this.state = {'portfolios': null, 'globalPerformance': null}; |
10 | } | 10 | } |
11 | 11 | ||
12 | load = () => { | 12 | load = () => { |
@@ -16,7 +16,13 @@ class AdminDashboard extends React.Component { | |||
16 | return; | 16 | return; |
17 | } | 17 | } |
18 | 18 | ||
19 | this.setState({'portfolios': data}); | 19 | this.setState({ |
20 | 'portfolios': data.portfolios, | ||
21 | 'globalPerformance': { | ||
22 | 'totalBtcValue': data.totalBtcValue, | ||
23 | 'totalBtcVariation': data.totalBtcVariation | ||
24 | } | ||
25 | }); | ||
20 | }.bind(this)); | 26 | }.bind(this)); |
21 | } | 27 | } |
22 | 28 | ||
@@ -28,15 +34,24 @@ class AdminDashboard extends React.Component { | |||
28 | if (this.state.portfolios === null) { | 34 | if (this.state.portfolios === null) { |
29 | return <div></div>; | 35 | return <div></div>; |
30 | } | 36 | } |
37 | |||
38 | var globalPerformance = <div className="row" key="global"> | ||
39 | <div className="col-6"><span>Total:</span></div> | ||
40 | <div className="col-6 text-center"> | ||
41 | <PFBalanceMinimal variationP={this.state.globalPerformance.totalBtcVariation} balance={this.state.globalPerformance.totalBtcValue} isPercent={false}/> | ||
42 | </div> | ||
43 | </div>; | ||
31 | var portfolios = Object.keys(this.state.portfolios).map(function(email) { | 44 | var portfolios = Object.keys(this.state.portfolios).map(function(email) { |
32 | return <div className="row" key={email}> | 45 | return <div className="row" key={email}> |
33 | <div className="col-6"><span>{email}:</span></div> | 46 | <div className="col-6"><span>{email}:</span></div> |
34 | <div className="col-6 text-center"> | 47 | <div className="col-6 text-center"> |
35 | <PFBalanceMinimal variationP={this.state.portfolios[email].performance.variationP} balance={this.state.portfolios[email].value} periodStart={this.state.portfolios[email].periodStart}/> | 48 | <PFBalanceMinimal variationP={this.state.portfolios[email].performance.variationP} balance={this.state.portfolios[email].value} isPercent={true}/> |
36 | </div> | 49 | </div> |
37 | </div>; | 50 | </div>; |
38 | }.bind(this)); | 51 | }.bind(this)); |
39 | 52 | ||
53 | portfolios.push(<hr key="hr"/>, globalPerformance); | ||
54 | |||
40 | return <Panel component={<div>{portfolios}</div>} title="Portfolios Overview"/>; | 55 | return <Panel component={<div>{portfolios}</div>} title="Portfolios Overview"/>; |
41 | } | 56 | } |
42 | 57 | ||
diff --git a/cmd/web/js/balance.jsx b/cmd/web/js/balance.jsx index 1915511..429538d 100644 --- a/cmd/web/js/balance.jsx +++ b/cmd/web/js/balance.jsx | |||
@@ -11,14 +11,19 @@ class CurrencyLogo extends React.Component { | |||
11 | } | 11 | } |
12 | } | 12 | } |
13 | 13 | ||
14 | var formatVariation = (variation) => { | 14 | var formatVariation = (variation, isPercent) => { |
15 | var variationAbs = Math.abs(variation); | 15 | var variationAbs = Math.abs(variation); |
16 | var suffix = ''; | ||
17 | if (isPercent === true) { | ||
18 | suffix = '%'; | ||
19 | } | ||
20 | |||
16 | if (variation === 0.0) { | 21 | if (variation === 0.0) { |
17 | return <span>{variationAbs}%</span>; | 22 | return <span>{variationAbs}{suffix}</span>; |
18 | } else if (variation > 0) { | 23 | } else if (variation > 0) { |
19 | return <span className="performance-up">+{variationAbs}%</span>; | 24 | return <span className="performance-up">+{variationAbs}{suffix}</span>; |
20 | } | 25 | } |
21 | return <span className="performance-down">-{variationAbs}%</span>; | 26 | return <span className="performance-down">-{variationAbs}{suffix}</span>; |
22 | }; | 27 | }; |
23 | 28 | ||
24 | 29 | ||
@@ -46,7 +51,7 @@ class CurrencyRate extends React.Component { | |||
46 | <div className="d-inline col-2">{this.props.quantity}</div> | 51 | <div className="d-inline col-2">{this.props.quantity}</div> |
47 | <div className="d-inline col-2">{this.props.BTCValue}</div> | 52 | <div className="d-inline col-2">{this.props.BTCValue}</div> |
48 | <div className="d-inline col-2">{this.props.weight}%</div> | 53 | <div className="d-inline col-2">{this.props.weight}%</div> |
49 | <div className="d-inline col-2">{formatVariation(this.props.positionPerformanceP)}</div> | 54 | <div className="d-inline col-2">{formatVariation(this.props.positionPerformanceP, true)}</div> |
50 | </div> | 55 | </div> |
51 | </React.Fragment>; | 56 | </React.Fragment>; |
52 | } | 57 | } |
@@ -87,7 +92,7 @@ class PFBalance extends React.Component { | |||
87 | <em>since {date}</em> | 92 | <em>since {date}</em> |
88 | </div> | 93 | </div> |
89 | <div className="col-4 variation text-center"> | 94 | <div className="col-4 variation text-center"> |
90 | <strong>{formatVariation(this.props.variationP)}</strong> | 95 | <strong>{formatVariation(this.props.variationP, true)}</strong> |
91 | </div> | 96 | </div> |
92 | </div> | 97 | </div> |
93 | </div> | 98 | </div> |
@@ -100,7 +105,7 @@ class PFBalanceMinimal extends React.Component { | |||
100 | return <React.Fragment> | 105 | return <React.Fragment> |
101 | <div className="balance"> | 106 | <div className="balance"> |
102 | <div className="col-12"> | 107 | <div className="col-12"> |
103 | <CurrencyLogo currency="BTC" /> <span><strong>{this.props.balance}</strong> <strong>{formatVariation(this.props.variationP)}</strong></span> | 108 | <CurrencyLogo currency="BTC" /> <span><strong>{this.props.balance}</strong> <strong>{formatVariation(this.props.variationP, this.props.isPercent)}</strong></span> |
104 | </div> | 109 | </div> |
105 | </div> | 110 | </div> |
106 | </React.Fragment>; | 111 | </React.Fragment>; |