mirror of
https://github.com/bendtherules/smallcase-portfolio-builder.git
synced 2026-08-18 13:52:19 +00:00
Add portfolio overview (w/o chart)
This commit is contained in:
@@ -11,6 +11,8 @@ class PortfolioBuilderApp extends Component {
|
||||
super(props);
|
||||
|
||||
this.allScripPrices = data.price;
|
||||
this.allScripEPS = data.eps;
|
||||
|
||||
this.state = {
|
||||
portfolioScripPrices: {
|
||||
// scrip name : current price
|
||||
@@ -102,6 +104,7 @@ class PortfolioBuilderApp extends Component {
|
||||
addScripToPortfolio={this.addScripToPortfolio}
|
||||
/>
|
||||
<PortfolioManager
|
||||
allScripEPS={this.allScripEPS}
|
||||
portfolioScripPrices={this.state.portfolioScripPrices}
|
||||
portfolioScripCounts={this.state.portfolioScripCounts}
|
||||
addScripToPortfolio={this.addScripToPortfolio}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.portfolio-manager {
|
||||
margin: 2em 0;
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.portfolio-manager .section-title .title-box {
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
.portfolio-manager .body {
|
||||
margin-left: 1em;
|
||||
margin-bottom: 2em;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
@@ -95,7 +94,6 @@
|
||||
right: 0.5em;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
|
||||
border-radius: 50%;
|
||||
background-color: #EE6723;
|
||||
color: white;
|
||||
@@ -120,7 +118,7 @@
|
||||
.portfolio-manager button {
|
||||
position: relative;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
min-height: 1em;
|
||||
}
|
||||
|
||||
.portfolio-manager button .btn-text {
|
||||
@@ -156,3 +154,56 @@
|
||||
.portfolio-manager .rupee-sign {
|
||||
font-family: PingFangSC-Light, serif;
|
||||
}
|
||||
|
||||
/* Portfolio Overview */
|
||||
|
||||
.portfolio-manager .portfolio-overview .overview-header {
|
||||
width: 100%;
|
||||
font-size: 1.5em;
|
||||
color: #1D70CA;
|
||||
margin-top: 0.25em;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.portfolio-manager .overview-body {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.portfolio-manager .overview-body .overview-chart, .portfolio-manager .overview-body .overview-details {
|
||||
float: left;
|
||||
width: 50%;
|
||||
min-height: 2em;
|
||||
}
|
||||
|
||||
.portfolio-manager .overview-body .overview-details {
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
.portfolio-manager .overview-card {
|
||||
float: left;
|
||||
width: 50%;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.portfolio-manager .overview-card .card-title {
|
||||
font-size: 1.25em;
|
||||
padding: .5em 0;
|
||||
color: #287DCE;
|
||||
}
|
||||
|
||||
.portfolio-manager .overview-card .card-details {
|
||||
font-size: 1.75em;
|
||||
font-weight: 300;
|
||||
padding-left: .25em;
|
||||
}
|
||||
|
||||
.portfolio-manager .overview-details .build-portfolio {
|
||||
width: 100%;
|
||||
font-size: 1.25em;
|
||||
margin: 1em 0;
|
||||
padding: 1em;
|
||||
background-image: linear-gradient(-90deg, #2BC4DD 0%, #3489D1 100%);
|
||||
color: white;
|
||||
text-align: center;
|
||||
box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.30);
|
||||
}
|
||||
@@ -10,6 +10,7 @@ class PortfolioManager extends Component {
|
||||
|
||||
calcNetWorth() {
|
||||
let netWorth = 0;
|
||||
|
||||
Object.keys(this.props.portfolioScripCounts).forEach((scripName) => {
|
||||
const count = this.props.portfolioScripCounts[scripName];
|
||||
const price = this.props.portfolioScripPrices[scripName];
|
||||
@@ -19,6 +20,27 @@ class PortfolioManager extends Component {
|
||||
return netWorth;
|
||||
}
|
||||
|
||||
calcTotalEarnings() {
|
||||
let totalEarnings = 0;
|
||||
Object.keys(this.props.portfolioScripCounts).forEach((scripName) => {
|
||||
const count = this.props.portfolioScripCounts[scripName];
|
||||
const eps = this.props.allScripEPS[scripName];
|
||||
totalEarnings += (eps * count);
|
||||
});
|
||||
|
||||
return totalEarnings;
|
||||
}
|
||||
|
||||
calcPortfolioPE() {
|
||||
const portfolioPE = (this.calcNetWorth() / this.calcTotalEarnings());
|
||||
|
||||
if (Number.isNaN(portfolioPE)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return portfolioPE;
|
||||
}
|
||||
|
||||
weightInPortfolio(scripName) {
|
||||
const count = this.props.portfolioScripCounts[scripName];
|
||||
const price = this.props.portfolioScripPrices[scripName];
|
||||
@@ -31,21 +53,11 @@ class PortfolioManager extends Component {
|
||||
return weight;
|
||||
}
|
||||
|
||||
render() {
|
||||
renderPortfolioEditor() {
|
||||
const portfolioScripPrices = this.props.portfolioScripPrices;
|
||||
const portfolioScripCounts = this.props.portfolioScripCounts;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="portfolio-manager"
|
||||
onDragOver={(ev) => { ev.preventDefault(); }}
|
||||
onDrop={(ev) => {
|
||||
const scripName = ev.dataTransfer.getData('text/plain');
|
||||
this.props.addScripToPortfolio(scripName);
|
||||
}}
|
||||
>
|
||||
<SectionTitle titleText="Manage Portfolio" />
|
||||
|
||||
<div className="body">
|
||||
<div className="portfolio-editor">
|
||||
<div className="editor-header">
|
||||
<div className="section-stock">
|
||||
@@ -78,20 +90,20 @@ class PortfolioManager extends Component {
|
||||
</div>
|
||||
<div className="section-price">
|
||||
<span className="rupee-sign">₹</span>
|
||||
{Math.round(this.props.portfolioScripPrices[scripName])}
|
||||
{Math.round(portfolioScripPrices[scripName])}
|
||||
</div>
|
||||
<div className="section-shares">
|
||||
<button
|
||||
className="shares-decrement-btn"
|
||||
disabled={
|
||||
this.props.portfolioScripCounts[scripName] <= 1
|
||||
portfolioScripCounts[scripName] <= 1
|
||||
}
|
||||
onClick={() => { this.props.addPortfolioScripCount(scripName, -1); }}
|
||||
>
|
||||
<span className="btn-text">-</span>
|
||||
</button>
|
||||
<span className="shares-value">
|
||||
{this.props.portfolioScripCounts[scripName]}
|
||||
{portfolioScripCounts[scripName]}
|
||||
</span>
|
||||
<button
|
||||
className="shares-increment-btn"
|
||||
@@ -116,12 +128,73 @@ class PortfolioManager extends Component {
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
renderPortfolioOverview() {
|
||||
const portfolioScripPrices = this.props.portfolioScripPrices;
|
||||
|
||||
return (
|
||||
<div className="portfolio-overview">
|
||||
<div className="overview-header">
|
||||
Portfolio Overview
|
||||
</div>
|
||||
<div className="overview-body">
|
||||
<div className="overview-chart">
|
||||
</div>
|
||||
<div className="overview-details">
|
||||
<div className="overview-card card-stocks">
|
||||
<div className="card-title">Stocks</div>
|
||||
<div className="card-details">
|
||||
{Object.keys(portfolioScripPrices).length}
|
||||
</div>
|
||||
</div>
|
||||
<div className="overview-card card-net-worth">
|
||||
<div className="card-title">Net Worth</div>
|
||||
<div className="card-details">
|
||||
<span className="rupee-sign">₹</span>
|
||||
{
|
||||
Math.round(this.calcNetWorth())
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="overview-card card-pe-ratio">
|
||||
<div className="card-title">P/E Ratio</div>
|
||||
<div className="card-details">
|
||||
{
|
||||
Math.round(this.calcPortfolioPE())
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="clearfix" />
|
||||
<button className="build-portfolio">
|
||||
BUILD PORTFOLIO
|
||||
</button>
|
||||
</div>
|
||||
<div className="clearfix" />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div
|
||||
className="portfolio-manager"
|
||||
onDragOver={(ev) => { ev.preventDefault(); }}
|
||||
onDrop={(ev) => {
|
||||
const scripName = ev.dataTransfer.getData('text/plain');
|
||||
this.props.addScripToPortfolio(scripName);
|
||||
}}
|
||||
>
|
||||
<SectionTitle titleText="Manage Portfolio" />
|
||||
|
||||
<div className="body">
|
||||
{this.renderPortfolioEditor()}
|
||||
{this.renderPortfolioOverview()}
|
||||
<div className="clearfix"></div>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user