Frontend app directory structure
This commit is contained in:
@@ -0,0 +1,131 @@
|
||||
var Router = ReactRouter,
|
||||
Route = Router.Route,
|
||||
Link = Router.Link,
|
||||
RouteHandler = Router.RouteHandler,
|
||||
DefaultRoute = Router.DefaultRoute,
|
||||
NotFoundRoute = Router.NotFoundRoute;
|
||||
|
||||
var App = React.createClass({displayName: "App",
|
||||
mixins: [Router.Navigation],
|
||||
render: function(){
|
||||
return (
|
||||
React.createElement("section", {className: "app"},
|
||||
React.createElement(Menu, null),
|
||||
React.createElement(RouteHandler, null)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var Menu = React.createClass({displayName: "Menu",
|
||||
mixins: [Router.Navigation, Router.State],
|
||||
api_url: "/api/teams?org=",
|
||||
|
||||
getInitialState: function() {
|
||||
return {teams: []};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.loadTeams();
|
||||
},
|
||||
|
||||
loadTeams: function() {
|
||||
$.get(this.api_url + this.getParams().org, function(res){
|
||||
this.setState({teams: res})
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var renderTeam = function(team) {
|
||||
return (
|
||||
React.createElement("li", {key: team.slug, className: "nav team"},
|
||||
React.createElement(Link, {to: "team", params: {org: team.owner, team: team.slug}}, team.name)
|
||||
)
|
||||
)
|
||||
};
|
||||
return (
|
||||
React.createElement("section", {className: "menu"},
|
||||
React.createElement("ul", null,
|
||||
React.createElement("li", {key: "empact", className: "nav empact"},
|
||||
React.createElement(Link, {to: "dashboard", params: {org: this.getParams().org}}, "Empact")
|
||||
),
|
||||
React.createElement("li", {key: "dash", className: "nav dash"},
|
||||
React.createElement(Link, {to: "dashboard", params: {org: this.getParams().org}}, "Dashboard")
|
||||
),
|
||||
React.createElement("li", {key: "teams-header", className: "nav header"}, "Teams:"),
|
||||
this.state.teams.map(renderTeam)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var Dashboard = React.createClass({displayName: "Dashboard",
|
||||
render: function(){
|
||||
return (
|
||||
React.createElement(RouteHandler, null)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var OrgStats = React.createClass({displayName: "OrgStats",
|
||||
mixins: [Router.Navigation, Router.State],
|
||||
render: function(){
|
||||
return (
|
||||
React.createElement("section", {className: "content"}, "Org stats for ", this.getParams().org)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var TeamStats = React.createClass({displayName: "TeamStats",
|
||||
mixins: [Router.Navigation, Router.State],
|
||||
render: function(){
|
||||
var url = "/api/stat/teams/top?org="+ this.getParams().org +"&from=1417878086&to=1425654067";
|
||||
return (
|
||||
React.createElement("section", {className: "content"},
|
||||
React.createElement("div", {className: "left"},
|
||||
React.createElement(BarChart, {url: url})
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var UserStats = React.createClass({displayName: "UserStats",
|
||||
render: function(){
|
||||
return (
|
||||
React.createElement("section", {className: "content"}, "User stats!")
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var RepoStats = React.createClass({displayName: "RepoStats",
|
||||
render: function(){
|
||||
return (
|
||||
React.createElement("section", {className: "content"}, "Repo Stats!")
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var NotFound = React.createClass({displayName: "NotFound",
|
||||
render: function(){
|
||||
return (
|
||||
React.createElement("section", {className: "content"}, "NOT FOUND :(")
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var routes = [
|
||||
React.createElement(Route, {name: "root", path: "/app/", handler: App},
|
||||
React.createElement(Route, {name: "dashboard", path: ":org", handler: Dashboard},
|
||||
React.createElement(DefaultRoute, {handler: OrgStats}),
|
||||
React.createElement(Route, {name: "team", path: "teams/:team", handler: TeamStats}),
|
||||
React.createElement(Route, {name: "user", path: "users/:user", handler: UserStats}),
|
||||
React.createElement(Route, {name: "repo", path: "repos/:repo", handler: RepoStats})
|
||||
),
|
||||
React.createElement(NotFoundRoute, {handler: NotFound})
|
||||
)
|
||||
];
|
||||
Router.run(routes, Router.HistoryLocation, function(Handler) {
|
||||
React.render(React.createElement(Handler, null), document.body);
|
||||
});
|
||||
@@ -0,0 +1,131 @@
|
||||
var Router = ReactRouter,
|
||||
Route = Router.Route,
|
||||
Link = Router.Link,
|
||||
RouteHandler = Router.RouteHandler,
|
||||
DefaultRoute = Router.DefaultRoute,
|
||||
NotFoundRoute = Router.NotFoundRoute;
|
||||
|
||||
var App = React.createClass({
|
||||
mixins: [Router.Navigation],
|
||||
render: function(){
|
||||
return (
|
||||
<section className="app">
|
||||
<Menu/>
|
||||
<RouteHandler/>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var Menu = React.createClass({
|
||||
mixins: [Router.Navigation, Router.State],
|
||||
api_url: "/api/teams?org=",
|
||||
|
||||
getInitialState: function() {
|
||||
return {teams: []};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
this.loadTeams();
|
||||
},
|
||||
|
||||
loadTeams: function() {
|
||||
$.get(this.api_url + this.getParams().org, function(res){
|
||||
this.setState({teams: res})
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var renderTeam = function(team) {
|
||||
return (
|
||||
<li key={team.slug} className="nav team">
|
||||
<Link to="team" params={{org: team.owner, team: team.slug}}>{team.name}</Link>
|
||||
</li>
|
||||
)
|
||||
};
|
||||
return (
|
||||
<section className="menu">
|
||||
<ul>
|
||||
<li key="empact" className="nav empact">
|
||||
<Link to="dashboard" params={{org: this.getParams().org}}>Empact</Link>
|
||||
</li>
|
||||
<li key="dash" className="nav dash">
|
||||
<Link to="dashboard" params={{org: this.getParams().org}}>Dashboard</Link>
|
||||
</li>
|
||||
<li key="teams-header" className="nav header">Teams:</li>
|
||||
{this.state.teams.map(renderTeam)}
|
||||
</ul>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var Dashboard = React.createClass({
|
||||
render: function(){
|
||||
return (
|
||||
<RouteHandler/>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var OrgStats = React.createClass({
|
||||
mixins: [Router.Navigation, Router.State],
|
||||
render: function(){
|
||||
return (
|
||||
<section className="content">Org stats for {this.getParams().org}</section>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var TeamStats = React.createClass({
|
||||
mixins: [Router.Navigation, Router.State],
|
||||
render: function(){
|
||||
var url = "/api/stat/teams/top?org="+ this.getParams().org +"&from=1417878086&to=1425654067";
|
||||
return (
|
||||
<section className="content">
|
||||
<div className="left">
|
||||
<BarChart url={url} />
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var UserStats = React.createClass({
|
||||
render: function(){
|
||||
return (
|
||||
<section className="content">User stats!</section>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var RepoStats = React.createClass({
|
||||
render: function(){
|
||||
return (
|
||||
<section className="content">Repo Stats!</section>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var NotFound = React.createClass({
|
||||
render: function(){
|
||||
return (
|
||||
<section className="content">NOT FOUND :(</section>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
var routes = [
|
||||
<Route name="root" path="/app/" handler={App}>
|
||||
<Route name="dashboard" path=":org" handler={Dashboard}>
|
||||
<DefaultRoute handler={OrgStats} />
|
||||
<Route name="team" path="teams/:team" handler={TeamStats} />
|
||||
<Route name="user" path="users/:user" handler={UserStats} />
|
||||
<Route name="repo" path="repos/:repo" handler={RepoStats} />
|
||||
</Route>
|
||||
<NotFoundRoute handler={NotFound}/>
|
||||
</Route>
|
||||
];
|
||||
Router.run(routes, Router.HistoryLocation, function(Handler) {
|
||||
React.render(<Handler/>, document.body);
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
var BarChart = React.createClass({displayName: "BarChart",
|
||||
barHeight: 40,
|
||||
barMargin: 5,
|
||||
|
||||
getInitialState: function() {
|
||||
return {points: []};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
$.get(this.props.url, function(res){
|
||||
this.setState({points: res});
|
||||
}.bind(this))
|
||||
},
|
||||
|
||||
height: function() {
|
||||
if (this.state.points.length === 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return this.y(this.state.points.length) - this.barMargin;
|
||||
}
|
||||
},
|
||||
|
||||
y: function(i) {
|
||||
return i*(this.barHeight + this.barMargin);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var renderPoint = function(point, i) {
|
||||
return (
|
||||
React.createElement("g", {key: point.item},
|
||||
React.createElement("rect", {
|
||||
fill: colorFor(point.item),
|
||||
width: point.value,
|
||||
height: this.barHeight,
|
||||
x: "0",
|
||||
y: this.y(i)}),
|
||||
React.createElement("text", {x: "20", y: this.y(i) + 25}, point.item + ": " + point.value)
|
||||
)
|
||||
);
|
||||
}.bind(this)
|
||||
return (
|
||||
React.createElement("svg", {className: "bar_chart", width: "100%", height: this.height()},
|
||||
this.state.points.map(renderPoint)
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,47 @@
|
||||
var BarChart = React.createClass({
|
||||
barHeight: 40,
|
||||
barMargin: 5,
|
||||
|
||||
getInitialState: function() {
|
||||
return {points: []};
|
||||
},
|
||||
|
||||
componentDidMount: function() {
|
||||
$.get(this.props.url, function(res){
|
||||
this.setState({points: res});
|
||||
}.bind(this))
|
||||
},
|
||||
|
||||
height: function() {
|
||||
if (this.state.points.length === 0) {
|
||||
return 0;
|
||||
} else {
|
||||
return this.y(this.state.points.length) - this.barMargin;
|
||||
}
|
||||
},
|
||||
|
||||
y: function(i) {
|
||||
return i*(this.barHeight + this.barMargin);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var renderPoint = function(point, i) {
|
||||
return (
|
||||
<g key={point.item}>
|
||||
<rect
|
||||
fill={colorFor(point.item)}
|
||||
width={point.value}
|
||||
height={this.barHeight}
|
||||
x="0"
|
||||
y={this.y(i)} />
|
||||
<text x="20" y={this.y(i) + 25}>{point.item + ": " + point.value}</text>
|
||||
</g>
|
||||
);
|
||||
}.bind(this)
|
||||
return (
|
||||
<svg className="bar_chart" width="100%" height={this.height()}>
|
||||
{this.state.points.map(renderPoint)}
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
// Colors source: http://graphicdesign.stackexchange.com/revisions/3815/8
|
||||
var Colors = [
|
||||
"#000000", "#FFFF00", "#1CE6FF", "#FF34FF", "#FF4A46", "#008941", "#006FA6", "#A30059",
|
||||
"#FFDBE5", "#7A4900", "#0000A6", "#63FFAC", "#B79762", "#004D43", "#8FB0FF", "#997D87",
|
||||
"#5A0007", "#809693", "#FEFFE6", "#1B4400", "#4FC601", "#3B5DFF", "#4A3B53", "#FF2F80",
|
||||
"#61615A", "#BA0900", "#6B7900", "#00C2A0", "#FFAA92", "#FF90C9", "#B903AA", "#D16100",
|
||||
"#DDEFFF", "#000035", "#7B4F4B", "#A1C299", "#300018", "#0AA6D8", "#013349", "#00846F",
|
||||
"#372101", "#FFB500", "#C2FFED", "#A079BF", "#CC0744", "#C0B9B2", "#C2FF99", "#001E09",
|
||||
"#00489C", "#6F0062", "#0CBD66", "#EEC3FF", "#456D75", "#B77B68", "#7A87A1", "#788D66",
|
||||
"#885578", "#FAD09F", "#FF8A9A", "#D157A0", "#BEC459", "#456648", "#0086ED", "#886F4C",
|
||||
"#34362D", "#B4A8BD", "#00A6AA", "#452C2C", "#636375", "#A3C8C9", "#FF913F", "#938A81",
|
||||
"#575329", "#00FECF", "#B05B6F", "#8CD0FF", "#3B9700", "#04F757", "#C8A1A1", "#1E6E00",
|
||||
"#7900D7", "#A77500", "#6367A9", "#A05837", "#6B002C", "#772600", "#D790FF", "#9B9700",
|
||||
"#549E79", "#FFF69F", "#201625", "#72418F", "#BC23FF", "#99ADC0", "#3A2465", "#922329",
|
||||
"#5B4534", "#FDE8DC", "#404E55", "#0089A3", "#CB7E98", "#A4E804", "#324E72", "#6A3A4C",
|
||||
"#83AB58", "#001C1E", "#D1F7CE", "#004B28", "#C8D0F6", "#A3A489", "#806C66", "#222800",
|
||||
"#BF5650", "#E83000", "#66796D", "#DA007C", "#FF1A59", "#8ADBB4", "#1E0200", "#5B4E51",
|
||||
"#C895C5", "#320033", "#FF6832", "#66E1D3", "#CFCDAC", "#D0AC94", "#7ED379", "#012C58",
|
||||
"#7A7BFF", "#D68E01", "#353339", "#78AFA1", "#FEB2C6", "#75797C", "#837393", "#943A4D",
|
||||
"#B5F4FF", "#D2DCD5", "#9556BD", "#6A714A", "#001325", "#02525F", "#0AA3F7", "#E98176",
|
||||
"#DBD5DD", "#5EBCD1", "#3D4F44", "#7E6405", "#02684E", "#962B75", "#8D8546", "#9695C5",
|
||||
"#E773CE", "#D86A78", "#3E89BE", "#CA834E", "#518A87", "#5B113C", "#55813B", "#E704C4",
|
||||
"#00005F", "#A97399", "#4B8160", "#59738A", "#FF5DA7", "#F7C9BF", "#643127", "#513A01",
|
||||
"#6B94AA", "#51A058", "#A45B02", "#1D1702", "#E20027", "#E7AB63", "#4C6001", "#9C6966",
|
||||
"#64547B", "#97979E", "#006A66", "#391406", "#F4D749", "#0045D2", "#006C31", "#DDB6D0",
|
||||
"#7C6571", "#9FB2A4", "#00D891", "#15A08A", "#BC65E9", "#FFFFFE", "#C6DC99", "#203B3C",
|
||||
"#671190", "#6B3A64", "#F5E1FF", "#FFA0F2", "#CCAA35", "#374527", "#8BB400", "#797868",
|
||||
"#C6005A", "#3B000A", "#C86240", "#29607C", "#402334", "#7D5A44", "#CCB87C", "#B88183",
|
||||
"#AA5199", "#B5D6C3", "#A38469", "#9F94F0", "#A74571", "#B894A6", "#71BB8C", "#00B433",
|
||||
"#789EC9", "#6D80BA", "#953F00", "#5EFF03", "#E4FFFC", "#1BE177", "#BCB1E5", "#76912F",
|
||||
"#003109", "#0060CD", "#D20096", "#895563", "#29201D", "#5B3213", "#A76F42", "#89412E",
|
||||
"#1A3A2A", "#494B5A", "#A88C85", "#F4ABAA", "#A3F3AB", "#00C6C8", "#EA8B66", "#958A9F",
|
||||
"#BDC9D2", "#9FA064", "#BE4700", "#658188", "#83A485", "#453C23", "#47675D", "#3A3F00",
|
||||
"#061203", "#DFFB71", "#868E7E", "#98D058", "#6C8F7D", "#D7BFC2", "#3C3E6E", "#D83D66",
|
||||
"#2F5D9B", "#6C5E46", "#D25B88", "#5B656C", "#00B57F", "#545C46", "#866097", "#365D25",
|
||||
"#252F99", "#00CCFF", "#674E60", "#FC009C", "#92896B"
|
||||
];
|
||||
|
||||
function randomColor() {
|
||||
return Colors[Math.floor(Math.random()*Colors.length)];
|
||||
}
|
||||
|
||||
// Source: http://stackoverflow.com/a/7616484
|
||||
function colorFor(token) {
|
||||
var hash = 0, i, chr, len;
|
||||
if (token.length == 0) return hash;
|
||||
for (i = 0, len = token.length; i < len; i++) {
|
||||
chr = token.charCodeAt(i);
|
||||
hash = ((hash << 5) - hash) + chr;
|
||||
hash |= 0; // Convert to 32bit integer
|
||||
}
|
||||
|
||||
return Colors[Math.abs(hash) % Colors.length];
|
||||
}
|
||||
Reference in New Issue
Block a user