Contact Requests in admin panel
This commit is contained in:
11
adminPanel/src/elements/footer.js
Normal file
11
adminPanel/src/elements/footer.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import React from "react";
|
||||
|
||||
export default function Footer() {
|
||||
|
||||
return (
|
||||
<footer className={"main-footer"}>
|
||||
Theme: <strong>Copyright © 2014-2019 <a href={"http://adminlte.io"}>AdminLTE.io</a>. <b>Version</b> 3.0.3</strong>
|
||||
CMS: <strong><a href={"https://git.romanh.de/Projekte/web-base"}>WebBase</a></strong>. <b>Version</b> 1.2.6
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
101
adminPanel/src/elements/header.js
Normal file
101
adminPanel/src/elements/header.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import * as React from "react";
|
||||
import Icon from "./icon";
|
||||
import {useState} from "react";
|
||||
import {getPeriodString} from "../global";
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
export default function Header(props) {
|
||||
|
||||
const parent = {
|
||||
notifications: props.notifications || [ ],
|
||||
};
|
||||
|
||||
const [dropdownVisible, showDropdown] = useState(false);
|
||||
const mailIcon = <Icon icon={"envelope"} type={"fas"} />;
|
||||
|
||||
let notificationCount = parent.notifications.length;
|
||||
let notificationText = "No new notifications";
|
||||
|
||||
if(notificationCount === 1) {
|
||||
notificationText = "1 new notification";
|
||||
} else if(notificationCount > 1) {
|
||||
notificationText = notificationCount + " new notification";
|
||||
}
|
||||
|
||||
let notificationItems = [];
|
||||
for (let i = 0; i < parent.notifications.length; i++) {
|
||||
const notification = parent.notifications[i];
|
||||
const uid = notification.uid;
|
||||
const createdAt = getPeriodString(notification["created_at"]);
|
||||
notificationItems.push(
|
||||
<Link to={"/admin/logs?notification=" + uid} className={"dropdown-item"} key={"notification-" + uid}>
|
||||
{mailIcon}
|
||||
<span className={"ml-2"}>{notification.title}</span>
|
||||
<span className={"float-right text-muted text-sm"}>{createdAt}</span>
|
||||
</Link>);
|
||||
}
|
||||
|
||||
function onToggleSidebar() {
|
||||
let classes = document.body.classList;
|
||||
if (classes.contains("sidebar-collapse")) {
|
||||
classes.remove("sidebar-collapse");
|
||||
classes.add("sidebar-open");
|
||||
} else {
|
||||
classes.add("sidebar-collapse");
|
||||
classes.remove("sidebar-add");
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<nav className={"main-header navbar navbar-expand navbar-white navbar-light"}>
|
||||
|
||||
{/*Left navbar links */}
|
||||
<ul className={"navbar-nav"}>
|
||||
<li className={"nav-item"}>
|
||||
<a href={"#"} className={"nav-link"} role={"button"} onClick={onToggleSidebar}>
|
||||
<Icon icon={"bars"}/>
|
||||
</a>
|
||||
</li>
|
||||
<li className={"nav-item d-none d-sm-inline-block"}>
|
||||
<Link to={"/admin/dashboard"} className={"nav-link"}>
|
||||
Home
|
||||
</Link>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{/* SEARCH FORM */}
|
||||
<form className={"form-inline ml-3"}>
|
||||
<div className={"input-group input-group-sm"}>
|
||||
<input className={"form-control form-control-navbar"} type={"search"} placeholder={"Search"} aria-label={"Search"} />
|
||||
<div className={"input-group-append"}>
|
||||
<button className={"btn btn-navbar"} type={"submit"}>
|
||||
<Icon icon={"search"}/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{/* Right navbar links */}
|
||||
<ul className={"navbar-nav ml-auto"}>
|
||||
|
||||
{/* Notifications Dropdown Menu */}
|
||||
<li className={"nav-item dropdown"} onClick={() => showDropdown(!dropdownVisible)}>
|
||||
<a href={"#"} className={"nav-link"} data-toggle={"dropdown"}>
|
||||
<Icon icon={"bell"} type={"far"} />
|
||||
<span className={"badge badge-warning navbar-badge"} style={{display: (notificationCount > 0 ? "block" : "none")}}>
|
||||
{notificationCount}
|
||||
</span>
|
||||
</a>
|
||||
<div className={"dropdown-menu dropdown-menu-lg dropdown-menu-right " + (dropdownVisible ? " show" : "")}>
|
||||
<span className={"dropdown-item dropdown-header"}>
|
||||
{notificationText}
|
||||
</span>
|
||||
{notificationItems}
|
||||
<div className={"dropdown-divider"} />
|
||||
<Link to={"/admin/logs"} className={"dropdown-item dropdown-footer"}>See All Notifications</Link>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
141
adminPanel/src/elements/sidebar.js
Normal file
141
adminPanel/src/elements/sidebar.js
Normal file
@@ -0,0 +1,141 @@
|
||||
import React from 'react';
|
||||
import Icon from "./icon";
|
||||
import {Link, NavLink} from "react-router-dom";
|
||||
|
||||
export default function Sidebar(props) {
|
||||
|
||||
let parent = {
|
||||
showDialog: props.showDialog || function() {},
|
||||
api: props.api,
|
||||
notifications: props.notifications || [ ],
|
||||
contactRequests: props.contactRequests || [ ],
|
||||
filesPath: props.filesPath || null
|
||||
};
|
||||
|
||||
function onLogout() {
|
||||
parent.api.logout().then(obj => {
|
||||
if (obj.success) {
|
||||
document.location = "/admin";
|
||||
} else {
|
||||
parent.showDialog("Error logging out: " + obj.msg, "Error logging out");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const menuItems = {
|
||||
"dashboard": {
|
||||
"name": "Dashboard",
|
||||
"icon": "tachometer-alt"
|
||||
},
|
||||
"visitors": {
|
||||
"name": "Visitor Statistics",
|
||||
"icon": "chart-bar",
|
||||
},
|
||||
"users": {
|
||||
"name": "Users & Groups",
|
||||
"icon": "users"
|
||||
},
|
||||
"pages": {
|
||||
"name": "Pages & Routes",
|
||||
"icon": "copy",
|
||||
},
|
||||
"settings": {
|
||||
"name": "Settings",
|
||||
"icon": "tools"
|
||||
},
|
||||
"logs": {
|
||||
"name": "Logs & Notifications",
|
||||
"icon": "file-medical-alt"
|
||||
},
|
||||
"contact": {
|
||||
"name": "Contact Requests",
|
||||
"icon": "comments"
|
||||
},
|
||||
"help": {
|
||||
"name": "Help",
|
||||
"icon": "question-circle"
|
||||
},
|
||||
};
|
||||
|
||||
let numNotifications = parent.notifications.length;
|
||||
if (numNotifications > 0) {
|
||||
if (numNotifications > 9) numNotifications = "9+";
|
||||
menuItems["logs"]["badge"] = { type: "warning", value: numNotifications };
|
||||
}
|
||||
|
||||
console.log("sidebar", parent.contactRequests);
|
||||
let numUnreadContactMessages = 0;
|
||||
for (const contactRequest of parent.contactRequests) {
|
||||
numUnreadContactMessages += contactRequest.unread;
|
||||
}
|
||||
if (numUnreadContactMessages > 0) {
|
||||
menuItems["contact"]["badge"] = { type: "info", value: numUnreadContactMessages };
|
||||
}
|
||||
|
||||
let li = [];
|
||||
for (let id in menuItems) {
|
||||
let obj = menuItems[id];
|
||||
const badge = (obj.badge ? <span className={"right badge badge-" + obj.badge.type}>{obj.badge.value}</span> : <></>);
|
||||
|
||||
li.push(
|
||||
<li key={id} className={"nav-item"}>
|
||||
<NavLink to={"/admin/" + id} className={"nav-link"} activeClassName={"active"}>
|
||||
<Icon icon={obj.icon} className={"nav-icon"} /><p>{obj.name}{badge}</p>
|
||||
</NavLink>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
|
||||
let filePath = parent.filesPath;
|
||||
if (filePath) {
|
||||
li.push(<li className={"nav-item"} key={"files"}>
|
||||
<a href={filePath} className={"nav-link"} target={"_blank"} rel={"noopener"}>
|
||||
<Icon icon={"folder"} className={"nav-icon"} />
|
||||
<p>Files</p>
|
||||
</a>
|
||||
</li>);
|
||||
}
|
||||
|
||||
li.push(<li className={"nav-item"} key={"logout"}>
|
||||
<a href={"#"} onClick={() => onLogout()} className={"nav-link"}>
|
||||
<Icon icon={"arrow-left"} className={"nav-icon"} />
|
||||
<p>Logout</p>
|
||||
</a>
|
||||
</li>);
|
||||
|
||||
return (
|
||||
<aside className={"main-sidebar sidebar-dark-primary elevation-4"}>
|
||||
<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"}} />
|
||||
<span className={"brand-text font-weight-light ml-2"}>WebBase</span>
|
||||
</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"}>
|
||||
{/* IDK what this is */}
|
||||
<div className={"os-resize-observer-host"}>
|
||||
<div className={"os-resize-observer observed"} style={{left: "0px", right: "auto"}}/>
|
||||
</div>
|
||||
<div className={"os-size-auto-observer"} style={{height: "calc(100% + 1px)", float: "left"}}>
|
||||
<div className={"os-resize-observer observed"}/>
|
||||
</div>
|
||||
<div className={"os-content-glue"} style={{margin: "0px -8px"}}/>
|
||||
<div className={"os-padding"}>
|
||||
<div className={"os-viewport os-viewport-native-scrollbars-invisible"} style={{right: "0px", bottom: "0px"}}>
|
||||
<div className={"os-content"} style={{padding: "0px 0px", height: "100%", width: "100%"}}>
|
||||
<div className="user-panel mt-3 pb-3 mb-3 d-flex">
|
||||
<div className="info">
|
||||
<a href="#" className="d-block">Logged in as: {parent.api.user.name}</a>
|
||||
</div>
|
||||
</div>
|
||||
<nav className={"mt-2"}>
|
||||
<ul className={"nav nav-pills nav-sidebar flex-column"} data-widget={"treeview"} role={"menu"} data-accordion={"false"}>
|
||||
{li}
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user