diff --git a/frontend/js/app.js b/frontend/js/app.js
index b892f35..9bae870 100644
--- a/frontend/js/app.js
+++ b/frontend/js/app.js
@@ -25,7 +25,7 @@ import { ProtectedRoute, AdminRoute } from "./auth"
import store, { history } from "./store"
// Components
-import AdminPanel from "./components/admins/panel"
+import { AdminPanel } from "./components/admins/panel"
import Alert from "./components/alerts/alert"
import MovieList from "./components/movies/list"
import MoviesRoute from "./components/movies/route"
diff --git a/frontend/js/components/admins/modules.js b/frontend/js/components/admins/modules.js
new file mode 100644
index 0000000..6b99cb8
--- /dev/null
+++ b/frontend/js/components/admins/modules.js
@@ -0,0 +1,28 @@
+import React, { useEffect } from "react"
+import PropTypes from "prop-types"
+import { connect } from "react-redux"
+import { getAdminModules} from "../../actions/admins"
+
+import Modules from "../modules/modules"
+
+const AdminModulesConnected = ({ modules, loading, getAdminModules }) => {
+ useEffect(() => {
+ getAdminModules();
+ }, [getAdminModules])
+
+ return (
+
+ )
+}
+AdminModulesConnected.propTypes = {
+ modules: PropTypes.object,
+ loading: PropTypes.bool,
+ getAdminModules: PropTypes.func.isRequired,
+};
+
+const mapStateToProps = state => ({
+ loading: state.adminStore.get("fetchingModules"),
+ modules: state.adminStore.get("modules"),
+});
+
+export const AdminModules = connect(mapStateToProps, {getAdminModules})(AdminModulesConnected);
diff --git a/frontend/js/components/admins/panel.js b/frontend/js/components/admins/panel.js
index f32905b..874f082 100644
--- a/frontend/js/components/admins/panel.js
+++ b/frontend/js/components/admins/panel.js
@@ -1,50 +1,13 @@
-import React, { useState } from "react"
-import PropTypes from "prop-types"
-import { connect } from "react-redux"
-import {
- getUsers, getStats,
- getAdminModules, updateUser
-} from "../../actions/admins"
+import React from "react"
-import Modules from "../modules/modules"
-import { UserList } from "./users"
+import { UserList } from "./userList"
import { Stats } from "./stats"
+import { AdminModules } from "./modules"
-const AdminPanel = props => {
- const [fetched, setIsFetched] = useState(false);
- if (!fetched) {
- props.getUsers();
- props.getStats();
- props.getAdminModules();
- setIsFetched(true);
- }
-
- return (
-
-
-
-
-
- )
-}
-AdminPanel.propTypes = {
- stats: PropTypes.object,
- users: PropTypes.object,
- modules: PropTypes.object,
- updateUser: PropTypes.func.isRequired,
- getUsers: PropTypes.func.isRequired,
- getStats: PropTypes.func.isRequired,
- getAdminModules: PropTypes.func.isRequired,
-};
-
-const mapStateToProps = state => ({
- users: state.adminStore.get("users"),
- stats: state.adminStore.get("stats"),
- modules: state.adminStore.get("modules"),
-});
-const mapDispatchToProps = {
- getUsers, getStats,
- getAdminModules, updateUser
-}
-
-export default connect(mapStateToProps, mapDispatchToProps)(AdminPanel);
+export const AdminPanel = () => (
+
+
+
+
+
+)
diff --git a/frontend/js/components/admins/stat.js b/frontend/js/components/admins/stat.js
new file mode 100644
index 0000000..f4164a2
--- /dev/null
+++ b/frontend/js/components/admins/stat.js
@@ -0,0 +1,30 @@
+import React from "react"
+import PropTypes from "prop-types"
+
+import { TorrentsStat } from "./torrentsStat"
+
+export const Stat = ({ name, count, torrentCount, torrentCountById }) => (
+
+
+
+
+ {name}
+ {count}
+
+
+
+
+
+
+
+)
+Stat.propTypes = {
+ name: PropTypes.string,
+ count: PropTypes.number,
+ torrentCount: PropTypes.number,
+ torrentCountById: PropTypes.number,
+};
diff --git a/frontend/js/components/admins/stats.js b/frontend/js/components/admins/stats.js
index 184ac0c..fe8b132 100644
--- a/frontend/js/components/admins/stats.js
+++ b/frontend/js/components/admins/stats.js
@@ -1,61 +1,46 @@
-import React from "react"
+import React, { useEffect } from "react"
import PropTypes from "prop-types"
+import { connect } from "react-redux"
-export const Stats = props => (
-
-
-
-
-
-)
-Stats.propTypes = { stats: PropTypes.object }
+import { Stat } from "./stat"
-const Stat = props => (
-
-
-
-
- {props.name}
- {props.count}
-
-
-
-
-
-
-
-)
-Stat.propTypes = {
- name: PropTypes.string,
- count: PropTypes.number,
-};
+import { getStats } from "../../actions/admins"
-const TorrentsStat = function(props) {
- if (props.data.torrentCount === undefined) {
- return (No torrents);
- }
+const StatsConnected = ({ stats, getStats }) => {
+ useEffect(() => {
+ getStats();
+ }, [getStats])
- const percentage = Math.floor((props.data.torrentCountById * 100) / props.data.count);
return (
-
- {percentage}% with torrents
- - {props.data.torrentCount} total
-
- );
+
+
+
+
+
+ )
}
-TorrentsStat.propTypes = { data: PropTypes.object };
+StatsConnected.propTypes = {
+ stats: PropTypes.object,
+ getStats: PropTypes.func,
+}
+
+const mapStateToProps = state => ({
+ stats: state.adminStore.get("stats"),
+});
+
+export const Stats = connect(mapStateToProps, {getStats})(StatsConnected);
diff --git a/frontend/js/components/admins/torrentsStat.js b/frontend/js/components/admins/torrentsStat.js
new file mode 100644
index 0000000..fa8abbe
--- /dev/null
+++ b/frontend/js/components/admins/torrentsStat.js
@@ -0,0 +1,21 @@
+import React from "react"
+import PropTypes from "prop-types"
+
+export const TorrentsStat = ({ count, torrentCount, torrentCountById }) => {
+ if (torrentCount === undefined) {
+ return (No torrents);
+ }
+
+ const percentage = Math.floor((torrentCountById * 100) / count);
+ return (
+
+ {percentage}% with torrents
+ - {torrentCount} total
+
+ );
+}
+TorrentsStat.propTypes = {
+ count: PropTypes.number,
+ torrentCount: PropTypes.number,
+ torrentCountById: PropTypes.number,
+};
diff --git a/frontend/js/components/admins/user.js b/frontend/js/components/admins/user.js
new file mode 100644
index 0000000..b6a9ad5
--- /dev/null
+++ b/frontend/js/components/admins/user.js
@@ -0,0 +1,60 @@
+import React from "react"
+import PropTypes from "prop-types"
+
+import { UserEdit } from "./userEdit"
+
+export const User = ({
+ id,
+ admin,
+ activated,
+ name,
+ polochonActivated,
+ polochonUrl,
+ polochonName,
+ polochonId,
+ token,
+}) => {
+ return (
+
+ {id} |
+ {name} |
+
+
+ |
+
+
+ |
+
+ {polochonName !== "" ? polochonName : "-"}
+ {polochonUrl !== "" &&
+ ({polochonUrl})
+ }
+ |
+ {token} |
+
+
+ |
+
+
+ |
+
+ );
+}
+User.propTypes = {
+ id: PropTypes.string,
+ name: PropTypes.string,
+ polochonId: PropTypes.string,
+ polochonUrl: PropTypes.string,
+ polochonName: PropTypes.string,
+ token: PropTypes.string,
+ admin: PropTypes.bool,
+ activated: PropTypes.bool,
+ polochonActivated: PropTypes.bool,
+};
diff --git a/frontend/js/components/admins/userEdit.js b/frontend/js/components/admins/userEdit.js
new file mode 100644
index 0000000..fa3c1ce
--- /dev/null
+++ b/frontend/js/components/admins/userEdit.js
@@ -0,0 +1,104 @@
+import React, { useState } from "react"
+import PropTypes from "prop-types"
+import { connect } from "react-redux"
+import { List } from "immutable"
+
+import { updateUser } from "../../actions/admins"
+
+import Toggle from "react-bootstrap-toggle";
+
+import { PolochonSelect } from "../polochons/select"
+import { FormModal } from "../forms/modal"
+import { FormInput } from "../forms/input"
+
+const UserEditConnect = ({
+ id,
+ admin: initAdmin,
+ activated: initActivated,
+ polochonToken,
+ polochonId: initPolochonId,
+ polochonActivated: initPolochonActivated,
+ updateUser,
+ publicPolochons,
+}) => {
+ const [modal, setModal] = useState(false);
+ const [admin, setAdmin] = useState(initAdmin);
+ const [activated, setActivated] = useState(initActivated);
+ const [token, setToken] = useState(polochonToken);
+ const [polochonId, setPolochonId] = useState(initPolochonId);
+ const [polochonActivated, setPolochonActivated] = useState(initPolochonActivated);
+ const [password, setPassword] = useState("");
+
+ const handleSubmit = function(e) {
+ if (e) { e.preventDefault(); }
+ updateUser({
+ userId: id,
+ polochonToken: token,
+ admin,
+ activated,
+ polochonId,
+ polochonActivated,
+ password,
+ });
+ setModal(false);
+ };
+
+ return (
+
+ setModal(true)} />
+
+
+
+
+
+ setActivated(!activated)}
+ />
+
+
+
+
+ setAdmin(!admin)} />
+
+
+
+
+
+
+
+
+ setPolochonActivated(!polochonActivated)}
+ />
+
+
+
+
+ );
+}
+UserEditConnect.propTypes = {
+ id: PropTypes.string,
+ activated: PropTypes.bool,
+ admin: PropTypes.bool,
+ data: PropTypes.object,
+ updateUser: PropTypes.func,
+ polochonToken: PropTypes.string,
+ polochonId: PropTypes.string,
+ polochonActivated: PropTypes.bool,
+ publicPolochons: PropTypes.instanceOf(List),
+};
+
+const mapStateToProps = (state) => ({
+ publicPolochons: state.polochon.get("public"),
+});
+
+export const UserEdit = connect(mapStateToProps, {updateUser})(UserEditConnect);
diff --git a/frontend/js/components/admins/userList.js b/frontend/js/components/admins/userList.js
new file mode 100644
index 0000000..8e5a85f
--- /dev/null
+++ b/frontend/js/components/admins/userList.js
@@ -0,0 +1,63 @@
+import React, { useEffect } from "react"
+import PropTypes from "prop-types"
+import { List } from "immutable"
+import { connect } from "react-redux"
+
+import { User } from "./user"
+
+import { getUsers } from "../../actions/admins"
+import { getPolochons } from "../../actions/polochon"
+
+const mapStateToProps = state => ({
+ users: state.adminStore.get("users"),
+});
+const mapDispatchToProps = { getUsers, getPolochons };
+
+const UserListConnect = ({ users, getUsers, getPolochons }) => {
+ useEffect(() => {
+ getUsers();
+ getPolochons();
+ }, [getUsers, getPolochons])
+
+ return (
+
+
+
+
+ # |
+ Name |
+ Activated |
+ Admin |
+ Polochon URL |
+ Polochon token |
+ Polochon activated |
+ Actions |
+
+
+
+ {users.map((el, index) =>
+
+ )}
+
+
+
+ );
+};
+UserListConnect.propTypes = {
+ getUsers: PropTypes.func,
+ getPolochons: PropTypes.func,
+ users: PropTypes.PropTypes.instanceOf(List),
+};
+
+export const UserList = connect(mapStateToProps, mapDispatchToProps)(UserListConnect);
diff --git a/frontend/js/reducers/admins.js b/frontend/js/reducers/admins.js
index 330f7ed..35c4e92 100644
--- a/frontend/js/reducers/admins.js
+++ b/frontend/js/reducers/admins.js
@@ -1,6 +1,7 @@
import { Map, List, fromJS } from "immutable"
export const defaultState = Map({
+ "fetchingModules": false,
"users": List(),
"stats": Map({}),
"modules": Map({}),
@@ -9,7 +10,11 @@ export const defaultState = 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)),
- "ADMIN_GET_MODULES_FULFILLED": (state, action) => state.set("modules", fromJS(action.payload.response.data)),
+ "ADMIN_GET_MODULES_PENDING": state => state.set("fetchingModules", true),
+ "ADMIN_GET_MODULES_FULFILLED": (state, action) => state.merge(fromJS({
+ "modules": action.payload.response.data,
+ "fetchingModules": false,
+ })),
}
export default (state = defaultState, action) =>