Skip to content

Commit 1d520fc

Browse files
committed
Merge remote-tracking branch 'origin/split-pricing' into split-pricing
2 parents 13b1360 + 04cf17d commit 1d520fc

File tree

8 files changed

+191
-15
lines changed

8 files changed

+191
-15
lines changed

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"build": "./node_modules/.bin/webpack",
88
"dev-client": "./node_modules/.bin/webpack-dev-server --port 3002 --content-base public/",
99
"fullStart": "./node_modules/.bin/webpack && node ./bin/start",
10-
"debug": "node $NODE_DEBUG_OPTION ./bin/start"
10+
"debug": "node $NODE_DEBUG_OPTION ./bin/start",
11+
"test": "jest"
1112
},
1213
"repository": {
1314
"type": "git",
@@ -113,10 +114,12 @@
113114
},
114115
"devDependencies": {
115116
"babel-plugin-transform-async-to-generator": "^6.24.1",
117+
"jest": "^22.4.2",
116118
"react-hot-loader": "^3.0.0-beta.7",
119+
"servicebot-client": "^1.0.3",
117120
"supertest": "^3.0.0",
118121
"tape": "^4.8.0",
119-
"uglifyjs-webpack-plugin": "^1.0.1",
122+
"uglifyjs-webpack-plugin": "^1.2.4",
120123
"webpack-dev-server": "^1.14.1"
121124
}
122125
}

views/components/elements/dashboard/css/style.css

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,30 @@
2626
font-size: 2em;
2727
font-weight: 100;
2828
padding: 20px 0px;
29+
}
30+
31+
.offerings-widgets{
32+
background: white;
33+
margin: 15px 0;
34+
border-radius: 5px;
35+
}
36+
37+
.offerings-widget {
38+
padding: 5px 15px;
39+
text-align: center;
40+
}
41+
42+
.offerings-widget.master {
43+
border-bottom-left-radius: 5px;
44+
border-top-left-radius: 5px;
45+
background: #000000;
46+
color: white;
47+
text-align: left;
48+
}
49+
50+
.customer-chart-widget{
51+
background: #ffffff;
52+
padding: 5px;
53+
border-radius: 5px;
54+
margin: 5px 10px;
2955
}

views/components/elements/dashboard/dashboard-chart.jsx

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,4 +160,76 @@ class ServiceStatusChart extends React.Component {
160160

161161
}
162162

163-
export {ServiceOverTimeChart, ServiceStatusChart};
163+
164+
165+
class CustomerStatusChart extends React.Component {
166+
constructor(props){
167+
super(props);
168+
this.state = {
169+
loading: true,
170+
instances: {},
171+
containerWidth: this.props.containerWidth,
172+
chartData: {},
173+
chartOption: {}
174+
};
175+
176+
this.fetchInstances = this.fetchInstances.bind(this);
177+
}
178+
179+
componentDidMount(){
180+
this.fetchInstances();
181+
}
182+
183+
fetchInstances(){
184+
let self = this;
185+
let url = '/api/v1/service-instances';
186+
Fetcher(url).then(function (response) {
187+
188+
if(!response.error) {
189+
let statuses = _.uniq(_.map(response, (instance) => instance.status));
190+
let groupByStatus = _.groupBy(response, (instance) => {
191+
return instance.status ? instance.status : other
192+
});
193+
let serviceCountByStatus = _.map(groupByStatus, (group)=>{return(group.length)});
194+
195+
let data = {
196+
labels: statuses,
197+
datasets: [{
198+
data: serviceCountByStatus,
199+
backgroundColor: [ "#FF6384", "#36A2EB", "#FFCE56", "#B388FF" ],
200+
hoverBackgroundColor: [ "#FF6384", "#36A2EB", "#FFCE56", "#B388FF" ] }]
201+
};
202+
let options = {
203+
animation: {
204+
animateRotate: true,
205+
animateScale: true
206+
}
207+
};
208+
209+
self.setState({loading: false, instances: response, chartData: data, chartOptions: options});
210+
}else{
211+
self.setState({loading: false});
212+
}
213+
})
214+
}
215+
216+
render(){
217+
if(this.state.loading){
218+
return(
219+
<div>
220+
<Load/>
221+
</div>
222+
);
223+
}else{
224+
return(
225+
<div className={`customer-status-chart ${this.props.className}`}>
226+
<h3 className="chart-title">Customer Stats</h3>
227+
<RC2 data={this.state.chartData} options={this.state.chartOptions} type='pie'/>
228+
</div>
229+
);
230+
}
231+
}
232+
233+
}
234+
235+
export {ServiceOverTimeChart, ServiceStatusChart, CustomerStatusChart};

views/components/elements/dashboard/dashboard-widgets.jsx

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,13 @@ class Widget extends React.Component {
7070
return (
7171
<div className={`dashboard-widget ${this.getCSSClass()}`} onClick={this.goTo} style={style.widgetData}>
7272
<div className="widget-label" style={style.widgetLabel}>{this.state.data.label}</div>
73-
{this.state.data.value && <div className="widget-data">{this.getFormatted(this.state.data.value)}<span className="sub">{this.props.postFix}</span></div>}
73+
{this.state.data.value !== null && <div className="widget-data">{this.getFormatted(this.state.data.value)}<span className="sub">{this.props.postFix}</span></div>}
7474
{this.state.data.list &&
75-
<div>
75+
<div className="p-t-10 p-b-10">
7676
{this.state.data.list.map(listing =>
77-
<div>
78-
<span>{listing.label}</span>
79-
<span>{listing.value}</span>
77+
<div className="row p-l-20 p-r-20">
78+
<div className="col-md-10">{listing.label}</div>
79+
<div className="col-md-2 text-right">{listing.value}</div>
8080
</div>
8181
)}
8282
</div>
@@ -115,12 +115,20 @@ class DashboardWidgets extends React.Component {
115115
saleStat.push({label:'Requested Sales', value:this.state.data.salesStats.overall.requested});
116116
saleStat.push({label:'Waiting Cancellations', value:this.state.data.salesStats.overall.waitingCancellation});
117117
saleStat.push({label:'Cancelled Sales', value:this.state.data.salesStats.overall.cancelled});
118+
119+
//Unpaid charge logic
120+
let orange = false;
121+
let green = true;
122+
if(this.state.data.salesStats.overall.remainingCharges > 0) {
123+
orange = true;
124+
green = false;
125+
}
118126
return (
119127
<div>
120128
<div className="dashboard-widgets">
121129
<Widget data={{label: 'ARR', value: this.state.data.salesStats.subscriptionStats.annual}} postFix="/yr" type="price"/>
122130
<Widget data={{label: 'MRR', value: this.state.data.salesStats.subscriptionStats.month}} postFix="/mo" type="price"/>
123-
<Widget data={{label: 'Unpaid Charges', value: this.state.data.salesStats.overall.remainingCharges}} type="price"/>
131+
<Widget data={{label: 'Unpaid Charges', value: this.state.data.salesStats.overall.remainingCharges}} type="price" orange={orange} green={green}/>
124132
<Widget data={{label: 'Total Transactions', value: this.state.data.totalSales}} type="price" purple={true}/>
125133
</div>
126134
<div className="dashboard-widgets overalls">
@@ -135,4 +143,4 @@ class DashboardWidgets extends React.Component {
135143

136144
}
137145

138-
export {DashboardWidgets};
146+
export {DashboardWidgets, Widget};
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import React from 'react';
2+
import './css/style.css';
3+
4+
class OfferingsStatsWidgets extends React.Component {
5+
6+
constructor(props){
7+
super(props);
8+
}
9+
10+
render(){
11+
let self = this;
12+
let analytics = self.props.data;
13+
return (
14+
<div className="offerings-widgets row">
15+
<div className="offerings-widget master col-md-2">Total Offerings: <b>{analytics.offeringStats.total}</b></div>
16+
<div className="offerings-widget col-md-3">Subscriptions: <span className="status-badge green"><b>{analytics.offeringStats.totalSubscription}</b></span></div>
17+
<div className="offerings-widget col-md-3">Scheduled Payments: <span className="status-badge green"><b>{analytics.offeringStats.totalSplit}</b></span></div>
18+
<div className="offerings-widget col-md-2">One Times: <span className="status-badge green"><b>{analytics.offeringStats.totalOneTime}</b></span></div>
19+
<div className="offerings-widget col-md-2">Quotes: <span className="status-badge green"><b>{analytics.offeringStats.totalQuote}</b></span></div>
20+
</div>
21+
);
22+
}
23+
24+
}
25+
26+
export default OfferingsStatsWidgets;
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import React from 'react';
2+
import './css/style.css';
3+
import {Widget} from "../../elements/dashboard/dashboard-widgets.jsx";
4+
import {CustomerStatusChart} from "../../elements/dashboard/dashboard-chart.jsx";
5+
6+
class OverallStatsWidgets extends React.Component {
7+
8+
9+
constructor(props){
10+
super(props);
11+
}
12+
13+
render(){
14+
let self = this;
15+
let analytics = self.props.data;
16+
let saleStat = [];
17+
saleStat.push({label:'Total Sales', value: analytics.salesStats.overall.total});
18+
saleStat.push({label:'Customers who Purchased', value: analytics.salesStats.overall.customersWithOfferings});
19+
saleStat.push({label:'Active Sales', value: analytics.salesStats.overall.activeSales});
20+
saleStat.push({label:'Requested Sales', value: analytics.salesStats.overall.requested});
21+
saleStat.push({label:'Waiting Cancellations', value: analytics.salesStats.overall.waitingCancellation});
22+
saleStat.push({label:'Cancelled Sales', value: analytics.salesStats.overall.cancelled});
23+
return (
24+
<div className="row m-0">
25+
<div className="dashboard-widgets p-0 col-md-4">
26+
<Widget data={{label: 'Sales Stat', list: saleStat}} postFix="/yr" purple={true}/>
27+
</div>
28+
<div className="customer-chart-widget col-md-8">
29+
<CustomerStatusChart className="dashboard-charts"/>
30+
</div>
31+
</div>
32+
);
33+
}
34+
35+
}
36+
37+
export default OverallStatsWidgets;

views/components/elements/forms/login.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,14 +183,16 @@ class Login extends React.Component {
183183
<button onClick={this.handleLogin} type='submit'
184184
className="btn btn-raised btn-lg btn-primary btn-block">Sign in
185185
</button>
186+
<p className="sign-up-link">
187+
<Link to={{pathname: "/forgot-password", state: {fromLogin: false}}}> Forgot
188+
Password</Link>
189+
</p>
186190
{(this.props.options && this.props.options.allow_registration.value == 'true') &&
187191
<p className="sign-up-link">Don't have an account?
188192
<span><Link to={{
189193
pathname: "/signup",
190194
state: {fromLogin: true}
191-
}}> Sign up here</Link> or </span>
192-
<Link to={{pathname: "/forgot-password", state: {fromLogin: false}}}> Forgot
193-
Password</Link>
195+
}}> Sign up here</Link></span>
194196
</p>
195197
}
196198
</form>

views/components/pages/dashboard.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ import SVGIcons from "../utilities/svg-icons.jsx";
1414
import ServiceBotTableNoData from '../elements/bootstrap-tables/servicebot-table-no-data.jsx';
1515
let _ = require("lodash");
1616
import { connect } from "react-redux";
17-
//import OverallStatsWidgets from '../elements/dashboard/overall-stats-widgets.jsx';
17+
import OfferingsStatsWidgets from '../elements/dashboard/offerings-stats-widgets.jsx';
18+
import OverallStatsWidgets from '../elements/dashboard/overall-stats-widgets.jsx';
1819
//import SubscriptionStatsWidgets from '../elements/dashboard/subscription-widgets.jsx';
1920
//import UnSubscriptionStatsWidgets from '../elements/dashboard/un-subscription-widgets.jsx';
2021

@@ -82,7 +83,8 @@ class Dashboard extends React.Component {
8283
<div>
8384
<ContentTitle title="Welcome to your dashboard"/>
8485
<DashboardWidgets data={this.state.analytics}/>
85-
{/*<OverallStatsWidgets data={this.state.analytics} />*/}
86+
<OfferingsStatsWidgets data={this.state.analytics} />
87+
<OverallStatsWidgets data={this.state.analytics} />
8688
{/*<SubscriptionStatsWidgets data={this.state.analytics} />*/}
8789
{/*<UnSubscriptionStatsWidgets data={this.state.analytics} />*/}
8890
<div className="row">

0 commit comments

Comments
 (0)