React Routes
This commit is contained in:
parent
2f9115d24a
commit
fffd0bdbbf
217
admin/dist/main.js
vendored
217
admin/dist/main.js
vendored
File diff suppressed because one or more lines are too long
96
admin/package-lock.json
generated
96
admin/package-lock.json
generated
@ -6275,6 +6275,19 @@
|
|||||||
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
|
||||||
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
|
"integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ=="
|
||||||
},
|
},
|
||||||
|
"history": {
|
||||||
|
"version": "4.10.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz",
|
||||||
|
"integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.1.2",
|
||||||
|
"loose-envify": "^1.2.0",
|
||||||
|
"resolve-pathname": "^3.0.0",
|
||||||
|
"tiny-invariant": "^1.0.2",
|
||||||
|
"tiny-warning": "^1.0.0",
|
||||||
|
"value-equal": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"hmac-drbg": {
|
"hmac-drbg": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
|
||||||
@ -6285,6 +6298,14 @@
|
|||||||
"minimalistic-crypto-utils": "^1.0.1"
|
"minimalistic-crypto-utils": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"hoist-non-react-statics": {
|
||||||
|
"version": "3.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
|
||||||
|
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
|
||||||
|
"requires": {
|
||||||
|
"react-is": "^16.7.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"homedir-polyfill": {
|
"homedir-polyfill": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
|
||||||
@ -8191,6 +8212,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz",
|
||||||
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
|
"integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg=="
|
||||||
},
|
},
|
||||||
|
"mini-create-react-context": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-b0TytUgFSbgFJGzJqXPKCFCBWigAjpjo+Fl7Vf7ZbKRDptszpppKxXH6DRXEABZ/gcEQczeb0iZ7JvL8e8jjCA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.5.5",
|
||||||
|
"tiny-warning": "^1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"mini-css-extract-plugin": {
|
"mini-css-extract-plugin": {
|
||||||
"version": "0.9.0",
|
"version": "0.9.0",
|
||||||
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz",
|
||||||
@ -10674,6 +10704,52 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
|
||||||
},
|
},
|
||||||
|
"react-router": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.1.2",
|
||||||
|
"history": "^4.9.0",
|
||||||
|
"hoist-non-react-statics": "^3.1.0",
|
||||||
|
"loose-envify": "^1.3.1",
|
||||||
|
"mini-create-react-context": "^0.4.0",
|
||||||
|
"path-to-regexp": "^1.7.0",
|
||||||
|
"prop-types": "^15.6.2",
|
||||||
|
"react-is": "^16.6.0",
|
||||||
|
"tiny-invariant": "^1.0.2",
|
||||||
|
"tiny-warning": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"isarray": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||||
|
},
|
||||||
|
"path-to-regexp": {
|
||||||
|
"version": "1.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz",
|
||||||
|
"integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==",
|
||||||
|
"requires": {
|
||||||
|
"isarray": "0.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"react-router-dom": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==",
|
||||||
|
"requires": {
|
||||||
|
"@babel/runtime": "^7.1.2",
|
||||||
|
"history": "^4.9.0",
|
||||||
|
"loose-envify": "^1.3.1",
|
||||||
|
"prop-types": "^15.6.2",
|
||||||
|
"react-router": "5.2.0",
|
||||||
|
"tiny-invariant": "^1.0.2",
|
||||||
|
"tiny-warning": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-scripts": {
|
"react-scripts": {
|
||||||
"version": "3.4.1",
|
"version": "3.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-3.4.1.tgz",
|
||||||
@ -11265,6 +11341,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
|
||||||
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
|
"integrity": "sha1-six699nWiBvItuZTM17rywoYh0g="
|
||||||
},
|
},
|
||||||
|
"resolve-pathname": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng=="
|
||||||
|
},
|
||||||
"resolve-url": {
|
"resolve-url": {
|
||||||
"version": "0.2.1",
|
"version": "0.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
|
||||||
@ -12691,6 +12772,16 @@
|
|||||||
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
|
||||||
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
|
"integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q="
|
||||||
},
|
},
|
||||||
|
"tiny-invariant": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw=="
|
||||||
|
},
|
||||||
|
"tiny-warning": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="
|
||||||
|
},
|
||||||
"tmp": {
|
"tmp": {
|
||||||
"version": "0.0.33",
|
"version": "0.0.33",
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||||
@ -13062,6 +13153,11 @@
|
|||||||
"spdx-expression-parse": "^3.0.0"
|
"spdx-expression-parse": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"value-equal": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz",
|
||||||
|
"integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw=="
|
||||||
|
},
|
||||||
"vary": {
|
"vary": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
"moment": "^2.26.0",
|
"moment": "^2.26.0",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
|
"react-router-dom": "^5.2.0",
|
||||||
"react-scripts": "3.4.1"
|
"react-scripts": "3.4.1"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -9,6 +9,7 @@ import UserOverview from './users.js';
|
|||||||
import Overview from './overview.js'
|
import Overview from './overview.js'
|
||||||
import Icon from "./icon";
|
import Icon from "./icon";
|
||||||
import Dialog from "./dialog";
|
import Dialog from "./dialog";
|
||||||
|
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'
|
||||||
|
|
||||||
class AdminDashboard extends React.Component {
|
class AdminDashboard extends React.Component {
|
||||||
|
|
||||||
@ -16,7 +17,6 @@ class AdminDashboard extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
this.api = new API();
|
this.api = new API();
|
||||||
this.state = {
|
this.state = {
|
||||||
currentView: "dashboard",
|
|
||||||
loaded: false,
|
loaded: false,
|
||||||
dialog: { onClose: () => this.hideDialog() },
|
dialog: { onClose: () => this.hideDialog() },
|
||||||
notifications: { }
|
notifications: { }
|
||||||
@ -29,10 +29,6 @@ class AdminDashboard extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeView(view) {
|
|
||||||
this.setState({ ...this.state, currentView: view || "dashboard" });
|
|
||||||
}
|
|
||||||
|
|
||||||
showDialog(message, title) {
|
showDialog(message, title) {
|
||||||
const props = { show: true, message: message, title: title };
|
const props = { show: true, message: message, title: title };
|
||||||
this.setState({ ...this.state, dialog: { ...this.state.dialog, ...props } });
|
this.setState({ ...this.state, dialog: { ...this.state.dialog, ...props } });
|
||||||
@ -52,47 +48,51 @@ class AdminDashboard extends React.Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.api.fetchUser().then(Success => {
|
||||||
|
if (!Success) {
|
||||||
|
document.location = "/admin";
|
||||||
|
} else {
|
||||||
|
this.fetchNotifications();
|
||||||
|
setInterval(this.onUpdate.bind(this), 60000);
|
||||||
|
this.setState({...this.state, loaded: true});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|
||||||
if (!this.state.loaded) {
|
if (!this.state.loaded) {
|
||||||
this.api.fetchUser().then(Success => {
|
|
||||||
if (!Success) {
|
|
||||||
document.location = "/admin";
|
|
||||||
} else {
|
|
||||||
this.fetchNotifications();
|
|
||||||
setInterval(this.onUpdate.bind(this), 60000);
|
|
||||||
this.setState({...this.state, loaded: true});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return <b>Loading… <Icon icon={"spinner"} /></b>
|
return <b>Loading… <Icon icon={"spinner"} /></b>
|
||||||
}
|
}
|
||||||
|
|
||||||
const controlObj = {
|
const controlObj = {
|
||||||
notifications: this.state.notifications,
|
notifications: this.state.notifications,
|
||||||
currentView: this.state.currentView,
|
|
||||||
onChangeView: this.onChangeView.bind(this),
|
|
||||||
showDialog: this.showDialog.bind(this),
|
showDialog: this.showDialog.bind(this),
|
||||||
api: this.api
|
api: this.api
|
||||||
};
|
};
|
||||||
|
|
||||||
return <>
|
const createView = (view) => {
|
||||||
|
controlObj.currentView = view;
|
||||||
|
switch (view) {
|
||||||
|
case "users":
|
||||||
|
return <UserOverview {...controlObj} />;
|
||||||
|
case "dashboard":
|
||||||
|
default:
|
||||||
|
return <Overview {...controlObj} />;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return <Router>
|
||||||
<Header {...controlObj} />
|
<Header {...controlObj} />
|
||||||
<Sidebar {...controlObj} />
|
<Sidebar {...controlObj} />
|
||||||
<div className={"content-wrapper p-2"}>
|
<div className={"content-wrapper p-2"}>
|
||||||
<section className={"content"}>
|
<section className={"content"}>
|
||||||
{this.createContent()}
|
<Route path={"/admin/:view"} component={(obj) => createView(obj.match.params.view)}/>
|
||||||
<Dialog {...this.state.dialog}/>
|
<Dialog {...this.state.dialog}/>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</Router>
|
||||||
}
|
|
||||||
|
|
||||||
createContent() {
|
|
||||||
if (this.state.currentView === "users") {
|
|
||||||
return <UserOverview />
|
|
||||||
} else {
|
|
||||||
return <Overview />
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
export default class Overview extends React.Component {
|
export default class Overview extends React.Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return <div>Overview</div>
|
return <div>Overview</div>
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from "./icon";
|
import Icon from "./icon";
|
||||||
|
import {Link, NavLink} from "react-router-dom";
|
||||||
|
|
||||||
export default function Sidebar(props) {
|
export default function Sidebar(props) {
|
||||||
|
|
||||||
let parent = {
|
let parent = {
|
||||||
onChangeView: props.onChangeView || function() { },
|
|
||||||
showDialog: props.showDialog || function() {},
|
showDialog: props.showDialog || function() {},
|
||||||
api: props.api
|
api: props.api
|
||||||
};
|
};
|
||||||
|
|
||||||
function onChangeView(view) {
|
|
||||||
parent.onChangeView(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLogout() {
|
function onLogout() {
|
||||||
parent.api.logout().then(obj => {
|
parent.api.logout().then(obj => {
|
||||||
if (obj.success) {
|
if (obj.success) {
|
||||||
@ -29,7 +25,7 @@ export default function Sidebar(props) {
|
|||||||
"icon": "tachometer-alt"
|
"icon": "tachometer-alt"
|
||||||
},
|
},
|
||||||
"users": {
|
"users": {
|
||||||
"name": "Users",
|
"name": "Users & Groups",
|
||||||
"icon": "users"
|
"icon": "users"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
@ -51,14 +47,15 @@ export default function Sidebar(props) {
|
|||||||
let li = [];
|
let li = [];
|
||||||
for (let id in menuItems) {
|
for (let id in menuItems) {
|
||||||
let obj = menuItems[id];
|
let obj = menuItems[id];
|
||||||
let active = props.currentView === id ? " active" : "";
|
|
||||||
const badge = (obj.badge ? <span className={"right badge badge-" + obj.badge.type}>{obj.badge.value}</span> : <></>);
|
const badge = (obj.badge ? <span className={"right badge badge-" + obj.badge.type}>{obj.badge.value}</span> : <></>);
|
||||||
|
|
||||||
li.push(<li key={id} className={"nav-item"}>
|
li.push(
|
||||||
<a href={"#"} onClick={() => onChangeView(id)} className={"nav-link" + active}>
|
<li key={id} className={"nav-item"}>
|
||||||
<Icon icon={obj.icon} classes={"nav-icon"} /><p>{obj.name}{badge}</p>
|
<NavLink to={"/admin/" + id} className={"nav-link"} activeClassName={"active"}>
|
||||||
</a>
|
<Icon icon={obj.icon} classes={"nav-icon"} /><p>{obj.name}{badge}</p>
|
||||||
</li>);
|
</NavLink>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
li.push(<li className={"nav-item"} key={"logout"}>
|
li.push(<li className={"nav-item"} key={"logout"}>
|
||||||
@ -70,10 +67,10 @@ export default function Sidebar(props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className={"main-sidebar sidebar-dark-primary elevation-4"}>
|
<aside className={"main-sidebar sidebar-dark-primary elevation-4"}>
|
||||||
<a href={"#"} className={"brand-link"} onClick={() => onChangeView("dashboard")}>
|
<Link href={"#"} className={"brand-link"} to={"/admin/dashboard"}>
|
||||||
<img src={"/img/icons/logo.png"} alt={"Logo"} className={"brand-image img-circle elevation-3"} style={{opacity: ".8"}} />
|
<img src={"/img/icons/logo.png"} alt={"Logo"} className={"brand-image img-circle elevation-3"} style={{opacity: ".8"}} />
|
||||||
<span className={"brand-text font-weight-light ml-2"}>WebBase</span>
|
<span className={"brand-text font-weight-light ml-2"}>WebBase</span>
|
||||||
</a>
|
</Link>
|
||||||
|
|
||||||
<div className={"sidebar os-host os-theme-light os-host-overflow os-host-overflow-y os-host-resize-disabled os-host-scrollbar-horizontal-hidden os-host-transition"}>
|
<div className={"sidebar os-host os-theme-light os-host-overflow os-host-overflow-y os-host-resize-disabled os-host-scrollbar-horizontal-hidden os-host-transition"}>
|
||||||
{/* IDK what this is */}
|
{/* IDK what this is */}
|
||||||
@ -101,7 +98,6 @@ export default function Sidebar(props) {
|
|||||||
{li}
|
{li}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
217
js/admin.min.js
vendored
217
js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user