Add stats about the library
This commit is contained in:
parent
dec9547152
commit
eb02ff2b46
57
src/internal/admins/stats.go
Normal file
57
src/internal/admins/stats.go
Normal file
@ -0,0 +1,57 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/sirupsen/logrus"
|
||||
"gitlab.quimbo.fr/odwrtw/canape-sql/src/internal/web"
|
||||
)
|
||||
|
||||
const (
|
||||
moviesCountQuery = `SELECT COUNT(*) FROM movies;`
|
||||
showsCountQuery = `SELECT COUNT(*) FROM shows;`
|
||||
episodesCountQuery = `SELECT COUNT(*) FROM episodes;`
|
||||
)
|
||||
|
||||
// GetCount gets the count from a query
|
||||
func GetCount(db *sqlx.DB, query string) (int, error) {
|
||||
var count int
|
||||
err := db.QueryRow(query).Scan(&count)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// GetStatsHandler returns the stats of the app
|
||||
func GetStatsHandler(env *web.Env, w http.ResponseWriter, r *http.Request) error {
|
||||
log := env.Log.WithFields(logrus.Fields{
|
||||
"function": "admin.GetStatsHandler",
|
||||
})
|
||||
|
||||
log.Debug("getting stats")
|
||||
|
||||
stats := struct {
|
||||
MoviesCount int `json:"movies_count"`
|
||||
ShowsCount int `json:"shows_count"`
|
||||
EpisodesCount int `json:"episodes_count"`
|
||||
}{}
|
||||
|
||||
for _, s := range []struct {
|
||||
query string
|
||||
ptr *int
|
||||
}{
|
||||
{moviesCountQuery, &stats.MoviesCount},
|
||||
{showsCountQuery, &stats.ShowsCount},
|
||||
{episodesCountQuery, &stats.EpisodesCount},
|
||||
} {
|
||||
var err error
|
||||
*s.ptr, err = GetCount(env.Database, s.query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return env.RenderJSON(w, stats)
|
||||
}
|
@ -7,6 +7,13 @@ export function getUsers() {
|
||||
)
|
||||
}
|
||||
|
||||
export function getStats() {
|
||||
return request(
|
||||
"ADMIN_GET_STATS",
|
||||
configureAxios().get("/admins/stats")
|
||||
)
|
||||
}
|
||||
|
||||
export function updateUser(data) {
|
||||
return request(
|
||||
"ADMIN_UPDATE_USER",
|
||||
|
@ -4,10 +4,12 @@ import { bindActionCreators } from "redux"
|
||||
import { updateUser } from "../../actions/admins"
|
||||
|
||||
import UserList from "./users"
|
||||
import Stats from "./stats"
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
users : state.adminStore.get("users"),
|
||||
stats : state.adminStore.get("stats"),
|
||||
};
|
||||
}
|
||||
const mapDispatchToProps = (dipatch) =>
|
||||
@ -15,10 +17,15 @@ const mapDispatchToProps = (dipatch) =>
|
||||
|
||||
function AdminPanel(props) {
|
||||
return (
|
||||
<div>
|
||||
<Stats
|
||||
stats={props.stats}
|
||||
/>
|
||||
<UserList
|
||||
users={props.users}
|
||||
updateUser={props.updateUser}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
27
src/public/js/components/admins/stats.js
Normal file
27
src/public/js/components/admins/stats.js
Normal file
@ -0,0 +1,27 @@
|
||||
import React from "react"
|
||||
|
||||
export default function Stats(props) {
|
||||
return (
|
||||
<div>
|
||||
<h2 className="hidden-xs">Stats</h2>
|
||||
<Stat name="Movies" value={props.stats.get("movies_count")} />
|
||||
<Stat name="Shows" value={props.stats.get("shows_count")} />
|
||||
<Stat name="Episodes" value={props.stats.get("episodes_count")} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function Stat(props) {
|
||||
return (
|
||||
<div className="col-xs-4">
|
||||
<div className="panel panel-default">
|
||||
<div className="panel-heading">
|
||||
<h3 className="panel-title">{props.name}</h3>
|
||||
</div>
|
||||
<div className="panel-body">
|
||||
{props.value}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -2,10 +2,12 @@ import { Map, List, fromJS } from "immutable"
|
||||
|
||||
const defaultState = Map({
|
||||
"users": List(),
|
||||
"stats": Map({}),
|
||||
});
|
||||
|
||||
const handlers = {
|
||||
"ADMIN_LIST_USERS_FULFILLED": (state, action) => state.set("users", fromJS(action.payload.response.data)),
|
||||
"ADMIN_GET_STATS_FULFILLED": (state, action) => state.set("stats", fromJS(action.payload.response.data)),
|
||||
}
|
||||
|
||||
export default (state = defaultState, action) =>
|
||||
|
@ -12,7 +12,7 @@ import { fetchTorrents } from "./actions/torrents"
|
||||
import { userLogout, getUserInfos } from "./actions/users"
|
||||
import { fetchMovies, getMovieExploreOptions } from "./actions/movies"
|
||||
import { fetchShows, fetchShowDetails, getShowExploreOptions } from "./actions/shows"
|
||||
import { getUsers } from "./actions/admins"
|
||||
import { getUsers, getStats } from "./actions/admins"
|
||||
|
||||
import store from "./store"
|
||||
|
||||
@ -122,7 +122,7 @@ export default function getRoutes(App) {
|
||||
component: UserActivation,
|
||||
onEnter: function(nextState, replace, next) {
|
||||
if (!isLoggedIn()) {
|
||||
replace('/users/login');
|
||||
replace("/users/login");
|
||||
}
|
||||
if (isActivated()) {
|
||||
// User is already activated, redirect him to the default route
|
||||
@ -254,6 +254,7 @@ export default function getRoutes(App) {
|
||||
onEnter: function(nextState, replace, next) {
|
||||
adminCheck(nextState, replace, next, function() {
|
||||
store.dispatch(getUsers());
|
||||
store.dispatch(getStats());
|
||||
});
|
||||
},
|
||||
},
|
||||
|
@ -61,4 +61,5 @@ func setupRoutes(env *web.Env) {
|
||||
// Admin routes
|
||||
env.Handle("/admins/users", admin.GetUsersHandler).WithRole(users.AdminRole).Methods("GET")
|
||||
env.Handle("/admins/users", admin.UpdateUserHandler).WithRole(users.AdminRole).Methods("POST")
|
||||
env.Handle("/admins/stats", admin.GetStatsHandler).WithRole(users.AdminRole).Methods("GET")
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user