aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjloup <jean-loup.jamet@trainline.com>2018-07-19 18:00:20 +0200
committerjloup <jean-loup.jamet@trainline.com>2018-07-19 18:00:20 +0200
commit1fcb77583201f9979a839fcae2dd642edc25af96 (patch)
tree778f6aca2612fc277c612dcb748cacf2e0d975ac
parent574bf1e47f1b611449faa8fa5848ba63dfc7d0e9 (diff)
downloadFront-1fcb77583201f9979a839fcae2dd642edc25af96.tar.gz
Front-1fcb77583201f9979a839fcae2dd642edc25af96.tar.zst
Front-1fcb77583201f9979a839fcae2dd642edc25af96.zip
Display total balance/performance.v0.0.24
-rw-r--r--api/admin.go16
-rw-r--r--cmd/web/js/admin.jsx21
-rw-r--r--cmd/web/js/balance.jsx19
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
9type GetAllPortfoliosQuery struct { 10type 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
16func (q GetAllPortfoliosQuery) ValidateParams() *Error { 21func (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';
6class AdminDashboard extends React.Component { 6class 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>;