react fixes
This commit is contained in:
parent
95b803a1e4
commit
dfc9697ed8
8
admin/dist/main.js
vendored
8
admin/dist/main.js
vendored
File diff suppressed because one or more lines are too long
@ -33,4 +33,8 @@ export default class API {
|
|||||||
async logout() {
|
async logout() {
|
||||||
return this.apiCall("user/logout");
|
return this.apiCall("user/logout");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getNotifications() {
|
||||||
|
return this.apiCall("notifications/fetch");
|
||||||
|
}
|
||||||
};
|
};
|
@ -1,24 +1,11 @@
|
|||||||
import React, {useEffect, useState} from "react";
|
import React from "react";
|
||||||
|
|
||||||
function useStateFromProp(initialValue) {
|
|
||||||
const [value, setValue] = useState(initialValue);
|
|
||||||
|
|
||||||
useEffect(() => setValue(initialValue), [initialValue]);
|
|
||||||
|
|
||||||
return [value, setValue];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function Dialog(props) {
|
export default function Dialog(props) {
|
||||||
|
|
||||||
const [value, setValue] = useStateFromProp(props);
|
const show = props.show;
|
||||||
|
|
||||||
function onClose() {
|
|
||||||
setValue({ });
|
|
||||||
}
|
|
||||||
|
|
||||||
const show = typeof value.message !== "undefined";
|
|
||||||
const classes = "modal fade" + (show ? " show" : "");
|
const classes = "modal fade" + (show ? " show" : "");
|
||||||
const style = { paddingRight: "12px", display: (show ? "block" : "none") };
|
const style = { paddingRight: "12px", display: (show ? "block" : "none") };
|
||||||
|
const onClose = props.onClose || function() { };
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={classes} id="modal-default" style={style} aria-modal="true" onClick={() => onClose()}>
|
<div className={classes} id="modal-default" style={style} aria-modal="true" onClick={() => onClose()}>
|
||||||
|
@ -18,17 +18,38 @@ class AdminDashboard extends React.Component {
|
|||||||
this.state = {
|
this.state = {
|
||||||
currentView: "dashboard",
|
currentView: "dashboard",
|
||||||
loaded: false,
|
loaded: false,
|
||||||
dialog: { }
|
dialog: { onClose: () => this.hideDialog() },
|
||||||
|
notifications: { }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeView(view) {
|
onUpdate() {
|
||||||
this.setState({ ...this.state, currentView: view || "dashboard", dialog: { } });
|
if (this.state.loaded) {
|
||||||
|
this.fetchNotifications();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
showDialog(props) {
|
onChangeView(view) {
|
||||||
props = props || { };
|
this.setState({ ...this.state, currentView: view || "dashboard" });
|
||||||
this.setState({ ...this.state, dialog: props });
|
}
|
||||||
|
|
||||||
|
showDialog(message, title) {
|
||||||
|
const props = { show: true, message: message, title: title };
|
||||||
|
this.setState({ ...this.state, dialog: { ...this.state.dialog, ...props } });
|
||||||
|
}
|
||||||
|
|
||||||
|
hideDialog() {
|
||||||
|
this.setState({ ...this.state, dialog: { ...this.state.dialog, show: false } });
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchNotifications() {
|
||||||
|
this.api.getNotifications().then((res) => {
|
||||||
|
if (!res.success) {
|
||||||
|
this.showDialog("Error fetching notifications: " + res.msg, "Error fetching notifications");
|
||||||
|
} else {
|
||||||
|
this.setState({...this.state, notifications: res.notifications});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@ -38,16 +59,17 @@ class AdminDashboard extends React.Component {
|
|||||||
if (!Success) {
|
if (!Success) {
|
||||||
document.location = "/admin";
|
document.location = "/admin";
|
||||||
} else {
|
} else {
|
||||||
|
this.fetchNotifications();
|
||||||
|
setInterval(this.onUpdate.bind(this), 60000);
|
||||||
this.setState({...this.state, loaded: true});
|
this.setState({...this.state, loaded: true});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return <b>Loading… <Icon icon={"spinner"} /></b>
|
return <b>Loading… <Icon icon={"spinner"} /></b>
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("index.render, state=", this.state);
|
|
||||||
return <>
|
return <>
|
||||||
<Header />
|
<Header />
|
||||||
<Sidebar currentView={this.state.currentView} onChangeView={this.onChangeView.bind(this)} showDialog={this.showDialog.bind(this)} api={this.api} />
|
<Sidebar currentView={this.state.currentView} notifications={this.state.notifications} onChangeView={this.onChangeView.bind(this)} showDialog={this.showDialog.bind(this)} api={this.api} />
|
||||||
<div className={"content-wrapper p-2"}>
|
<div className={"content-wrapper p-2"}>
|
||||||
<section className={"content"}>
|
<section className={"content"}>
|
||||||
{this.createContent()}
|
{this.createContent()}
|
||||||
|
@ -1,78 +1,76 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from "./icon";
|
import Icon from "./icon";
|
||||||
|
|
||||||
export default class Sidebar extends React.Component {
|
export default function Sidebar(props) {
|
||||||
|
|
||||||
constructor(props) {
|
let parent = {
|
||||||
super(props);
|
onChangeView: props.onChangeView || function() { },
|
||||||
this.parent = {
|
showDialog: props.showDialog || function() {},
|
||||||
onChangeView: props.onChangeView || function() { },
|
api: props.api
|
||||||
showDialog: props.showDialog || function() {},
|
};
|
||||||
api: props.api
|
|
||||||
};
|
function onChangeView(view) {
|
||||||
this.state = { currentView: props.currentView, }
|
parent.onChangeView(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
onChangeView(view) {
|
function onLogout() {
|
||||||
this.setState({ ...this.state, currentView: view });
|
parent.api.logout().then(obj => {
|
||||||
this.parent.onChangeView(view);
|
if (obj.success) {
|
||||||
}
|
document.location = "/admin";
|
||||||
|
} else {
|
||||||
onLogout() {
|
parent.showDialog("Error logging out: " + obj.msg, "Error logging out");
|
||||||
this.parent.api.logout().then(obj => {
|
}
|
||||||
if (obj.success) {
|
|
||||||
document.location = "/admin";
|
|
||||||
} else {
|
|
||||||
this.parent.showDialog({message: "Error logging out: " + obj.msg, title: "Error logging out"});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
const menuItems = {
|
||||||
|
"dashboard": {
|
||||||
|
"name": "Dashboard",
|
||||||
|
"icon": "tachometer-alt"
|
||||||
|
},
|
||||||
|
"users": {
|
||||||
|
"name": "Users",
|
||||||
|
"icon": "users"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"name": "Settings",
|
||||||
|
"icon": "tools"
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"name": "Help",
|
||||||
|
"icon": "question-circle"
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const menuItems = {
|
let numNotifications = Object.keys(props.notifications).length;
|
||||||
"dashboard": {
|
if (numNotifications > 0) {
|
||||||
"name": "Dashboard",
|
if (numNotifications > 9) numNotifications = "9+";
|
||||||
"icon": "tachometer-alt"
|
menuItems["dashboard"]["badge"] = { type: "warning", value: numNotifications };
|
||||||
},
|
}
|
||||||
"users": {
|
|
||||||
"name": "Users",
|
|
||||||
"icon": "users"
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"name": "Settings",
|
|
||||||
"icon": "tools"
|
|
||||||
},
|
|
||||||
"help": {
|
|
||||||
"name": "Help",
|
|
||||||
"icon": "question-circle"
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
let li = [];
|
let li = [];
|
||||||
// li.push(<li className={"nav-item"} key={"logged-in-as"}><span className={""}>Logged in as: {this.parent.api.user.name}</span><hr/></li>);
|
for (let id in menuItems) {
|
||||||
// li.push(<li key={"hr"}><hr/></li>);
|
let obj = menuItems[id];
|
||||||
// li.push(<li key={"header"} className={"header"}>MAIN NAVIGATION</li>);
|
let active = props.currentView === id ? " active" : "";
|
||||||
|
const badge = (obj.badge ? <span className={"right badge badge-" + obj.badge.type}>{obj.badge.value}</span> : <></>);
|
||||||
|
|
||||||
for (let id in menuItems) {
|
li.push(<li key={id} className={"nav-item"}>
|
||||||
let obj = menuItems[id];
|
<a href={"#"} onClick={() => onChangeView(id)} className={"nav-link" + active}>
|
||||||
let active = this.state.currentView === id ? " active" : "";
|
<Icon icon={obj.icon} classes={"nav-icon"} /><p>{obj.name}{badge}</p>
|
||||||
li.push(<li key={id} className={"nav-item"}>
|
|
||||||
<a href={"#"} onClick={() => this.onChangeView(id)} className={"nav-link" + active}>
|
|
||||||
<Icon icon={obj.icon} classes={"nav-icon"} /><p>{obj.name}</p>
|
|
||||||
</a>
|
|
||||||
</li>);
|
|
||||||
}
|
|
||||||
|
|
||||||
li.push(<li className={"nav-item"} key={"logout"}>
|
|
||||||
<a href={"#"} onClick={() => this.onLogout()} className={"nav-link"}>
|
|
||||||
<Icon icon={"arrow-left"} classes={"nav-icon"} />
|
|
||||||
<p>Logout</p>
|
|
||||||
</a>
|
</a>
|
||||||
</li>);
|
</li>);
|
||||||
|
}
|
||||||
return <aside className={"main-sidebar sidebar-dark-primary elevation-4"}>
|
|
||||||
<a href={"#"} className={"brand-link"} onClick={() => this.onChangeView("dashboard")}>
|
li.push(<li className={"nav-item"} key={"logout"}>
|
||||||
|
<a href={"#"} onClick={() => onLogout()} className={"nav-link"}>
|
||||||
|
<Icon icon={"arrow-left"} classes={"nav-icon"} />
|
||||||
|
<p>Logout</p>
|
||||||
|
</a>
|
||||||
|
</li>);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<aside className={"main-sidebar sidebar-dark-primary elevation-4"}>
|
||||||
|
<a href={"#"} className={"brand-link"} onClick={() => onChangeView("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>
|
</a>
|
||||||
@ -93,7 +91,7 @@ export default class Sidebar extends React.Component {
|
|||||||
{/* LOGGED IN AS */}
|
{/* LOGGED IN AS */}
|
||||||
<div className="user-panel mt-3 pb-3 mb-3 d-flex">
|
<div className="user-panel mt-3 pb-3 mb-3 d-flex">
|
||||||
<div className="info">
|
<div className="info">
|
||||||
<a href="#" className="d-block">Logged in as: {this.parent.api.user.name}</a>
|
<a href="#" className="d-block">Logged in as: {parent.api.user.name}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -109,6 +107,5 @@ export default class Sidebar extends React.Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
}
|
)
|
||||||
|
}
|
||||||
};
|
|
||||||
|
@ -15,8 +15,8 @@ class LoginBody extends Body {
|
|||||||
public function loadView() {
|
public function loadView() {
|
||||||
parent::loadView();
|
parent::loadView();
|
||||||
$head = $this->getDocument()->getHead();
|
$head = $this->getDocument()->getHead();
|
||||||
$head->loadBootstrap();
|
|
||||||
$head->loadJQuery();
|
$head->loadJQuery();
|
||||||
|
$head->loadBootstrap();
|
||||||
$head->addJS(Script::CORE);
|
$head->addJS(Script::CORE);
|
||||||
$head->addCSS(Link::CORE);
|
$head->addCSS(Link::CORE);
|
||||||
$head->addJS(Script::ADMIN);
|
$head->addJS(Script::ADMIN);
|
||||||
|
8
js/admin.min.js
vendored
8
js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user