From 68557f512c2793b8d2523200239102da6ee111aa Mon Sep 17 00:00:00 2001 From: Abhas Bhattacharya Date: Wed, 11 Apr 2018 14:13:23 +0530 Subject: [PATCH] Complete portfolio manager functionalities --- .../PortfolioBuilderApp.css | 2 - .../PortfolioBuilderApp.jsx | 22 +++- .../PortfolioManager/PortfolioManager.css | 121 +++++++++++++++++- .../PortfolioManager/PortfolioManager.jsx | 118 ++++++++++++++--- src/Components/StockPicker/StockPicker.jsx | 2 +- 5 files changed, 245 insertions(+), 20 deletions(-) diff --git a/src/Components/PortfolioBuilderApp/PortfolioBuilderApp.css b/src/Components/PortfolioBuilderApp/PortfolioBuilderApp.css index d4eb51f..c2af1f3 100644 --- a/src/Components/PortfolioBuilderApp/PortfolioBuilderApp.css +++ b/src/Components/PortfolioBuilderApp/PortfolioBuilderApp.css @@ -16,6 +16,4 @@ .portfolio-builder-app>.body>.title { font-size: 2em; color: #17BCD9; - - padding-bottom: 1em; } \ No newline at end of file diff --git a/src/Components/PortfolioBuilderApp/PortfolioBuilderApp.jsx b/src/Components/PortfolioBuilderApp/PortfolioBuilderApp.jsx index 399c047..74ac5b7 100644 --- a/src/Components/PortfolioBuilderApp/PortfolioBuilderApp.jsx +++ b/src/Components/PortfolioBuilderApp/PortfolioBuilderApp.jsx @@ -21,6 +21,8 @@ class PortfolioBuilderApp extends Component { }; this.addScripToPortfolio = this.addScripToPortfolio.bind(this); + this.removeScripFromPortfolio = this.removeScripFromPortfolio.bind(this); + this.addPortfolioScripCount = this.addPortfolioScripCount.bind(this); } addScripToPortfolio(scripName) { @@ -32,7 +34,7 @@ class PortfolioBuilderApp extends Component { const oldPortfolioScripCounts = oldState.portfolioScripCounts; const newPortfolioScripCounts = deepCloneNaive(oldPortfolioScripCounts); - newPortfolioScripCounts[scripName] = newPortfolioScripCounts[scripName] || 0; + newPortfolioScripCounts[scripName] = newPortfolioScripCounts[scripName] || 1; return { portfolioScripPrices: newPortfolioScripPrices, @@ -61,6 +63,21 @@ class PortfolioBuilderApp extends Component { } } + addPortfolioScripCount(scripName, incrementBy) { + this.setState((oldState) => { + if (scripName in this.state.portfolioScripPrices) { + const oldPortfolioScripCounts = oldState.portfolioScripCounts; + const newPortfolioScripCounts = deepCloneNaive(oldPortfolioScripCounts); + newPortfolioScripCounts[scripName] += incrementBy; + + return { + portfolioScripCounts: newPortfolioScripCounts, + }; + } + return {}; + }); + } + calcRemainingScripPrices() { const remainingScripPrices = {}; Object.keys(this.allScripPrices).forEach((scripName) => { @@ -86,7 +103,10 @@ class PortfolioBuilderApp extends Component { /> diff --git a/src/Components/PortfolioManager/PortfolioManager.css b/src/Components/PortfolioManager/PortfolioManager.css index 1b97255..e65746b 100644 --- a/src/Components/PortfolioManager/PortfolioManager.css +++ b/src/Components/PortfolioManager/PortfolioManager.css @@ -10,4 +10,123 @@ .portfolio-manager .section-title .title-tail { border-top: 1.5em solid #15569C; -} \ No newline at end of file +} + +.portfolio-manager .body { + margin-left: 1em; + margin-bottom: 2em; + padding: 1em; +} + +.portfolio-manager .portfolio-editor, .portfolio-manager .portfolio-overview { + float: left; +} + +.portfolio-manager .portfolio-editor { + width: 45%; + padding-right: 1em; +} + +.portfolio-manager .portfolio-overview { + width: 55%; + padding-left: 1em; +} + +.portfolio-manager .editor-header, .portfolio-manager .editor-body { + width: 100%; +} + +.portfolio-manager .editor-header { + background-color: #8FB9E7; + color: white; + padding: 1em 0; +} + +.portfolio-manager .editor-body { + box-shadow: 0 0 .25em 0 rgba(0, 0, 0, 0.20); + border-radius: .25em; + min-height: 5em; + padding-bottom: 2em; +} + +.portfolio-manager .editor-body .scrip-line-item { + padding: .5em 0; +} + +.portfolio-manager .section-stock, .portfolio-manager .section-price, .portfolio-manager .section-shares, .portfolio-manager .section-weight { + float: left; + padding: 0.25em; +} + +.portfolio-manager .section-stock { + width: 35%; + padding-left: 1em; +} + +.portfolio-manager .section-shares { + width: 23%; +} + +.portfolio-manager .section-price, .portfolio-manager .section-weight { + width: 17%; +} + +.portfolio-manager .section-remove-btn { + float: left; + width: 8%; +} + +.portfolio-manager .editor-body .section-stock { + padding-left: 1.5em; + color: #287DCE; +} + +.portfolio-manager .editor-body .section-remove-btn { + text-align: center; +} + +.portfolio-manager .editor-body .section-price, .portfolio-manager .editor-body .section-weight { + text-align: right; + padding-right: 0.5em; +} + +.portfolio-manager button { + position: relative; + width: 1em; + height: 1em; +} + +/* +,-,remove Button styles */ + +.portfolio-manager button .btn-text { + position: absolute; + font-size: 1em; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); +} + +.portfolio-manager .section-shares { + border-radius: .25em; +} + +.portfolio-manager .section-shares>* { + display: block; + float: left; + width: 33.33%; + height: 1.25em; + border: 1px solid #DDDDDD; +} + +.portfolio-manager .section-shares .btn-text { + color: #287DCE; +} + +.portfolio-manager .section-shares .shares-value { + text-align: center; +} + +/* Rupee styling */ +.portfolio-manager .rupee-sign { + font-family: PingFangSC-Light, serif; + } \ No newline at end of file diff --git a/src/Components/PortfolioManager/PortfolioManager.jsx b/src/Components/PortfolioManager/PortfolioManager.jsx index 205751a..f6a2f72 100644 --- a/src/Components/PortfolioManager/PortfolioManager.jsx +++ b/src/Components/PortfolioManager/PortfolioManager.jsx @@ -8,6 +8,29 @@ class PortfolioManager extends Component { super(); } + calcNetWorth() { + let netWorth = 0; + Object.keys(this.props.portfolioScripCounts).forEach((scripName) => { + const count = this.props.portfolioScripCounts[scripName]; + const price = this.props.portfolioScripPrices[scripName]; + netWorth += (price * count); + }); + + return netWorth; + } + + weightInPortfolio(scripName) { + const count = this.props.portfolioScripCounts[scripName]; + const price = this.props.portfolioScripPrices[scripName]; + const weight = ((count * price) / this.calcNetWorth()) * 100; + + if (Number.isNaN(weight)) { + return 0; + } + + return weight; + } + render() { const portfolioScripPrices = this.props.portfolioScripPrices; @@ -22,21 +45,86 @@ class PortfolioManager extends Component { > -
- Please drop here -
    - { - Object.keys(portfolioScripPrices).map((scripName) => { - return ( -
  • - {scripName} | {portfolioScripPrices[scripName]} -
  • - ); - }) - } -
+
+
+
+
+ STOCK +
+
+ PRICE +
+
+ SHARES +
+
+ WEIGHT +
+
+ +
+
+
+
+ { + Object.keys(portfolioScripPrices).map((scripName) => { + return ( +
+
+ {scripName} +
+
+ + {Math.round(this.props.portfolioScripPrices[scripName])} +
+
+ + + {this.props.portfolioScripCounts[scripName]} + + +
+
+ { + Math.round(this.weightInPortfolio(scripName)) + } + % +
+
+ +
+
+
+ ); + }) + } + +
+
+
+ +
+
+
+
); } diff --git a/src/Components/StockPicker/StockPicker.jsx b/src/Components/StockPicker/StockPicker.jsx index 7452791..30b689e 100644 --- a/src/Components/StockPicker/StockPicker.jsx +++ b/src/Components/StockPicker/StockPicker.jsx @@ -100,7 +100,7 @@ class StockPicker extends Component {
- + {Math.round(currentPageScripPrices[scripName])}