Update the admin panel

This commit is contained in:
Grégoire Delattre 2019-05-15 14:39:34 +02:00 committed by Gogs
parent 56bc8d335c
commit 2897f73cb9
3 changed files with 176 additions and 229 deletions

View File

@ -1,37 +1,33 @@
import React from "react" import React from "react"
import PropTypes from "prop-types"
import { connect } from "react-redux" import { connect } from "react-redux"
import { bindActionCreators } from "redux" import { bindActionCreators } from "redux"
import { updateUser } from "../../actions/admins" import { updateUser } from "../../actions/admins"
import Modules from "../modules/modules" import Modules from "../modules/modules"
import UserList from "./users" import { UserList } from "./users"
import Stats from "./stats" import { Stats } from "./stats"
function mapStateToProps(state) { const AdminPanel = props => (
return { <React.Fragment>
users : state.adminStore.get("users"), <Stats stats={props.stats}/>
stats : state.adminStore.get("stats"), <UserList users={props.users} updateUser={props.updateUser}/>
modules : state.adminStore.get("modules"), <Modules modules={props.modules}/>
}; </React.Fragment>
} )
const mapDispatchToProps = (dipatch) => AdminPanel.propTypes = {
stats: PropTypes.object,
users: PropTypes.object,
modules: PropTypes.object,
updateUser: PropTypes.func,
};
const mapStateToProps = state => ({
users: state.adminStore.get("users"),
stats: state.adminStore.get("stats"),
modules: state.adminStore.get("modules"),
});
const mapDispatchToProps = dipatch =>
bindActionCreators({ updateUser }, dipatch) bindActionCreators({ updateUser }, dipatch)
function AdminPanel(props) {
return (
<div>
<Stats
stats={props.stats}
/>
<UserList
users={props.users}
updateUser={props.updateUser}
/>
<Modules
modules={props.modules}
/>
</div>
);
}
export default connect(mapStateToProps, mapDispatchToProps)(AdminPanel); export default connect(mapStateToProps, mapDispatchToProps)(AdminPanel);

View File

@ -1,50 +1,52 @@
import React from "react" import React from "react"
import PropTypes from "prop-types"
export default function Stats(props) { export const Stats = props => (
return ( <div>
<div> <h2 className="hidden-xs">Stats</h2>
<h2 className="hidden-xs">Stats</h2> <Stat
<Stat name="Movies"
name="Movies" count={props.stats.get("movies_count")}
count={props.stats.get("movies_count")} torrentCount={props.stats.get("movies_torrents_count")}
torrentCount={props.stats.get("movies_torrents_count")} torrentCountById={props.stats.get("movies_torrents_count_by_id")}
torrentCountById={props.stats.get("movies_torrents_count_by_id")} />
/> <Stat
<Stat name="Shows"
name="Shows" count={props.stats.get("shows_count")}
count={props.stats.get("shows_count")} torrentCount={props.stats.get("episodes_torrents_count")}
torrentCount={props.stats.get("episodes_torrents_count")} torrentCountById={props.stats.get("shows_torrents_count_by_id")}
torrentCountById={props.stats.get("shows_torrents_count_by_id")} />
/> <Stat
<Stat name="Episodes"
name="Episodes" count={props.stats.get("episodes_count")}
count={props.stats.get("episodes_count")} torrentCount={props.stats.get("episodes_torrents_count")}
torrentCount={props.stats.get("episodes_torrents_count")} torrentCountById={props.stats.get("episodes_torrents_count_by_id")}
torrentCountById={props.stats.get("episodes_torrents_count_by_id")} />
/> </div>
</div> )
); Stats.propTypes = { stats: PropTypes.object }
}
function Stat(props) { const Stat = props => (
return ( <div className="col-xs-4">
<div className="col-xs-4"> <div className="panel panel-default">
<div className="panel panel-default"> <div className="panel-heading">
<div className="panel-heading"> <h3 className="panel-title">
<h3 className="panel-title"> {props.name}
{props.name} <span className="label label-info pull-right">{props.count}</span>
<span className="label label-info pull-right">{props.count}</span> </h3>
</h3> </div>
</div> <div className="panel-body">
<div className="panel-body"> <TorrentsStat data={props} />
<TorrentsStat data={props} />
</div>
</div> </div>
</div> </div>
); </div>
} )
Stat.propTypes = {
name: PropTypes.string,
count: PropTypes.number,
};
function TorrentsStat(props) { const TorrentsStat = function(props) {
if (props.data.torrentCount === undefined) { if (props.data.torrentCount === undefined) {
return (<span>No torrents</span>); return (<span>No torrents</span>);
} }
@ -57,3 +59,4 @@ function TorrentsStat(props) {
</span> </span>
); );
} }
TorrentsStat.propTypes = { data: PropTypes.object };

View File

@ -1,189 +1,137 @@
import React from "react" import React, { useState } from "react"
import PropTypes from "prop-types"
import { List } from "immutable"
import { Button, Modal } from "react-bootstrap" import { Button, Modal } from "react-bootstrap"
import Toggle from "react-bootstrap-toggle"; import Toggle from "react-bootstrap-toggle";
export default function UserList(props) { export const UserList = props => (
return ( <div>
<div> <h2 className="hidden-xs">Users</h2>
<h2 className="hidden-xs">Users</h2> <h3 className="visible-xs">Users</h3>
<h3 className="visible-xs">Users</h3> <table className="table">
<table className="table"> <thead>
<thead> <tr className="active">
<tr className="active"> <th>#</th>
<th>#</th> <th>Name</th>
<th>Name</th> <th>Activated</th>
<th>Activated</th> <th>Admin</th>
<th>Admin</th> <th>Polochon URL</th>
<th>Polochon URL</th> <th>Polochon token</th>
<th>Polochon token</th> <th>Actions</th>
<th>Actions</th> </tr>
</tr> </thead>
</thead> <tbody>
<tbody> {props.users.map((el, index) =>
{props.users.map(function(el, index) { <User key={index} data={el} updateUser={props.updateUser}/>)}
return ( </tbody>
<User </table>
key={index} </div>
data={el} );
updateUser={props.updateUser} UserList.propTypes = {
/> users: PropTypes.PropTypes.instanceOf(List),
); updateUser: PropTypes.func,
})} };
</tbody>
</table>
</div>
);
}
function User(props) { const User = function(props) {
const polochonConfig = props.data.get("RawConfig").get("polochon"); const polochonConfig = props.data.get("RawConfig").get("polochon");
const polochonURL = polochonConfig ? polochonConfig.get("url") : "-"; const polochonUrl = polochonConfig ? polochonConfig.get("url") : "-";
const polochonToken = polochonConfig ? polochonConfig.get("token") : "-"; const polochonToken = polochonConfig ? polochonConfig.get("token") : "-";
return ( return (
<tr> <tr>
<td>{props.data.get("id")}</td> <td>{props.data.get("id")}</td>
<td>{props.data.get("Name")}</td> <td>{props.data.get("Name")}</td>
<td><UserActivationStatus data={props.data}/></td> <td><UserActivationStatus activated={props.data.get("Activated")}/></td>
<td><UserAdminStatus data={props.data}/></td> <td><UserAdminStatus admin={props.data.get("Admin")}/></td>
<td>{polochonURL}</td> <td>{polochonUrl}</td>
<td>{polochonToken}</td> <td>{polochonToken}</td>
<td> <td>
<UserEdit <UserEdit
data={props.data} data={props.data}
updateUser={props.updateUser} updateUser={props.updateUser}
polochonUrl={polochonUrl}
polochonToken={polochonToken}
/> />
</td> </td>
</tr> </tr>
); );
} }
User.propTypes = {
data: PropTypes.object,
updateUser: PropTypes.func,
};
function UserAdminStatus(props) { const UserAdminStatus = props => (
const admin = props.data.get("Admin"); <span className={props.admin ? "fa fa-check" : "fa fa-times"}></span>
const className = admin ? "fa fa-check" : "fa fa-times"; );
return (<span className={className}></span>); UserAdminStatus.propTypes = { admin: PropTypes.bool.isRequired };
}
function UserActivationStatus(props) { const UserActivationStatus = props => (
const activated = props.data.get("Activated"); <span className={props.activated ? "fa fa-check" : "fa fa-times text-danger"}></span>
const className = activated ? "fa fa-check" : "fa fa-times text-danger"; );
return (<span className={className}></span>); UserActivationStatus.propTypes = { activated: PropTypes.bool.isRequired };
}
class UserEdit extends React.PureComponent { function UserEdit(props) {
constructor(props) { const [modal, setModal] = useState(false);
super(props); const [admin, setAdmin] = useState(props.data.get("Admin"));
const [activated, setActivated] = useState(props.data.get("Activated"));
const [url, setUrl] = useState(props.polochonUrl);
const [token, setToken] = useState(props.polochonToken);
// User props const handleSubmit = function(e) {
const polochonConfig = props.data.get("RawConfig").get("polochon");
const polochonUrl = polochonConfig ? polochonConfig.get("url") : "";
const polochonToken = polochonConfig ? polochonConfig.get("token") : "";
// Functions
this.showModal = this.showModal.bind(this);
this.hideModal = this.hideModal.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleUrlInput = this.handleUrlInput.bind(this);
this.handleTokenInput = this.handleTokenInput.bind(this);
this.handleActivatedToggle = this.handleActivatedToggle.bind(this);
this.handleAdminToggle = this.handleAdminToggle.bind(this);
this.state = {
showModal: false,
polochonUrl: polochonUrl,
polochonToken: polochonToken,
activated: props.data.get("Activated"),
admin: props.data.get("Admin"),
};
}
showModal() {
this.setState({ showModal: true });
}
hideModal() {
this.setState({ showModal: false });
}
handleSubmit(e) {
if (e) { e.preventDefault(); } if (e) { e.preventDefault(); }
this.props.updateUser({ props.updateUser({
userId: this.props.data.get("id"), userId: props.data.get("id"),
admin: this.state.admin, admin: admin,
activated: this.state.activated, activated: activated,
polochonUrl: this.state.polochonUrl, polochonUrl: url,
polochonToken: this.state.polochonToken, polochonToken: token,
}); });
this.setState({ showModal: false }); setModal(false);
} };
handleTokenInput() {
this.setState({ polochonToken: this.refs.polochonToken.value }); return (
} <span>
handleUrlInput() { <span className="fa fa-pencil clickable" onClick={() => setModal(true)}></span>
this.setState({ polochonUrl: this.refs.polochonUrl.value }); <Modal show={modal} onHide={() => setModal(false)}>
} <Modal.Header closeButton>
handleActivatedToggle() { <Modal.Title>
this.setState({ activated: !this.state.activated }); <i className="fa fa-pencil"></i>
} &nbsp; Edit user - {props.data.get("Name")}
handleAdminToggle() { </Modal.Title>
this.setState({ admin: !this.state.admin }); </Modal.Header>
} <Modal.Body bsClass="modal-body admin-edit-user-modal">
render() { <form className="form-horizontal" onSubmit={(ev) => handleSubmit(ev)}>
return ( <div className="form-group">
<span> <label>Account status</label>
<span className="fa fa-pencil clickable" onClick={this.showModal}></span> <Toggle className="pull-right" on="Activated" off="Deactivated" active={activated} onClick={() => setActivated(!activated)}
<Modal show={this.state.showModal} onHide={this.hideModal}> />
<Modal.Header closeButton> </div>
<Modal.Title> <div className="form-group">
<i className="fa fa-pencil"></i> <label>Admin status</label>
&nbsp; Edit user - {this.props.data.get("Name")} <Toggle className="pull-right" on="Admin" off="User" active={admin} onClick={() => setAdmin(!admin)} />
</Modal.Title> </div>
</Modal.Header> <div className="form-group">
<Modal.Body bsClass="modal-body admin-edit-user-modal"> <label className="control-label">Polochon URL</label>
<form className="form-horizontal" onSubmit={(ev) => this.handleSubmit(ev)}> <input className="form-control" value={url} onChange={(e) => setUrl(e.target.value)}/>
<div className="form-group"> </div>
<label>Account status</label> <div className="form-group">
<Toggle <label className="control-label">Polochon token</label>
className="pull-right" <input className="form-control" value={token} onChange={(e) => setToken(e.target.value)} />
on="Activated" </div>
off="Deactivated" </form>
active={this.state.activated} </Modal.Body>
onClick={this.handleActivatedToggle} <Modal.Footer>
/> <Button bsStyle="success" onClick={handleSubmit}>Apply</Button>
</div> <Button onClick={() => setModal(false)}>Close</Button>
<div className="form-group"> </Modal.Footer>
<label>Admin status</label> </Modal>
<Toggle </span>
className="pull-right" );
on="Admin"
off="User"
active={this.state.admin}
onClick={this.handleAdminToggle}
/>
</div>
<div className="form-group">
<label className="control-label">Polochon URL</label>
<input
className="form-control"
value={this.state.polochonUrl}
onChange={this.handleUrlInput}
ref="polochonUrl"
/>
</div>
<div className="form-group">
<label className="control-label">Polochon token</label>
<input
className="form-control"
value={this.state.polochonToken}
onChange={this.handleTokenInput}
ref="polochonToken"
/>
</div>
</form>
</Modal.Body>
<Modal.Footer>
<Button bsStyle="success" onClick={this.handleSubmit}>Apply</Button>
<Button onClick={this.hideModal}>Close</Button>
</Modal.Footer>
</Modal>
</span>
);
}
} }
UserEdit.propTypes = {
data: PropTypes.object,
updateUser: PropTypes.func,
polochonUrl: PropTypes.string,
polochonToken: PropTypes.string,
};