yazid138 3 년 전
부모
커밋
a8fae6eafe
11개의 변경된 파일416개의 추가작업 그리고 505개의 파일을 삭제
  1. 12 0
      components/Layout/Header.js
  2. 0 66
      components/Layout/Menu.js
  3. 52 0
      components/Layout/MenuPT.js
  4. 273 318
      components/Layout/Sidebar.js
  5. 45 42
      components/Layout/SidebarUserBlock.js
  6. 3 3
      json/dataUser.js
  7. 8 0
      pages/app/_middleware.js
  8. 19 14
      pages/login.js
  9. 1 0
      pages/logout.js
  10. 0 58
      pages/singleview.js
  11. 3 4
      store/actions/user.js

+ 12 - 0
components/Layout/Header.js

@@ -1,4 +1,5 @@
 import React, { Component } from "react";
+import Router from "next/router";
 import PropTypes from "prop-types";
 import Link from "next/link";
 import { UncontrolledDropdown, DropdownToggle, DropdownMenu, DropdownItem, ListGroup, ListGroupItem } from "reactstrap";
@@ -50,6 +51,12 @@ class Header extends Component {
 		this.props.actions.toggleSetting("asideToggled");
 	};
 
+	handleLogout = (e) => {
+		e.preventDefault();
+		sessionStorage.clear();
+		Router.push({ pathname: "/login" });
+	};
+
 	resize() {
 		// all IE friendly dispatchEvent
 		var evt = document.createEvent("UIEvents");
@@ -176,6 +183,11 @@ class Header extends Component {
 							{/* END Dropdown menu */}
 						</UncontrolledDropdown>
 						{/* END Alert menu */}
+						<li className="nav-item">
+							<a className="nav-link" href="" onClick={this.handleLogout}>
+								<em className="icon-logout" />
+							</a>
+						</li>
 						{/* START Offsidebar button */}
 						<li className="nav-item">
 							<a className="nav-link" href="" onClick={this.toggleOffsidebar}>

+ 0 - 66
components/Layout/Menu.js

@@ -3,12 +3,6 @@ const Menu = [
 		heading: "Main Navigation",
 		translate: "sidebar.heading.HEADER",
 	},
-	// {
-	// 	name: "Login",
-	// 	path: "/login",
-	// 	icon: "icon-login",
-	// 	translate: "sidebar.nav.LOGIN",
-	// },
 	{
 		name: "Pelaporan",
 		path: "/app/pelaporan",
@@ -67,66 +61,6 @@ const Menu = [
 		icon: "icon-notebook",
 		translate: "sidebar.nav.PENCABUTAN_SANKSI",
 	},
-	{
-		heading: "Perguruan Tinggi",
-		translate: "sidebar.heading.PERGURUAN_TINGGI",
-	},
-	{
-		name: "Pemantauan",
-		path: "/app/pt/pemantauan",
-		icon: "icon-notebook",
-		translate: "sidebar.nav.PT_PEMANTAUAN",
-	},
-	{
-		name: "Pengajuan Keberatan",
-		icon: "icon-notebook",
-		translate: "sidebar.nav.PENGAJUAN_KEBERATAN",
-		submenu: [
-			{
-				name: "a. Permohonan Keberatan",
-				path: "/app/pt/keberatan",
-			},
-			{
-				name: "b. Jawaban atas permohonan keberatan",
-				path: "/app/pt/jawaban-keberatan",
-			},
-			{
-				name: "c. Jawaban atas permohonan banding",
-				path: "/app/pt/jawaban-banding",
-			},
-		],
-	},
-	{
-		name: "Dokumen Perbaikan",
-		path: "/app/pt/dokumen-perbaikan",
-		icon: "icon-notebook",
-		translate: "sidebar.nav.PT_DOKUMEN_PERBAIKAN",
-	},
-	{
-		name: "Permohonan Pencabutan Sanksi",
-		path: "/app/pt/pencabutan-sanksi",
-		icon: "icon-notebook",
-		translate: "sidebar.nav.PT_PENCABUTAN_SANKSI",
-	},
-	{
-		name: "Jawaban Permohonan Pencabutan Sanksi",
-		path: "/app/pt/jawaban-pencabutan-sanksi",
-		icon: "icon-notebook",
-		translate: "sidebar.nav.PT_JAWABAN_PENCABUTAN_SANKSI",
-	},
-
-	// {
-	// 	name: "FAQ",
-	// 	path: "/app/faq",
-	// 	icon: "icon-notebook",
-	// 	translate: "sidebar.nav.FAQ",
-	// },
-	// {
-	// 	name: "User List",
-	// 	path: "/app/userlist",
-	// 	icon: "icon-notebook",
-	// 	translate: "sidebar.nav.USERLIST",
-	// },
 ];
 
 export default Menu;

+ 52 - 0
components/Layout/MenuPT.js

@@ -0,0 +1,52 @@
+const MenuPT = [
+	{
+		heading: "Main Navigation",
+		translate: "sidebar.heading.HEADER",
+	},
+	{
+		name: "Pemantauan",
+		path: "/app/pt/pemantauan",
+		icon: "icon-notebook",
+		translate: "sidebar.nav.PT_PEMANTAUAN",
+	},
+	{
+		name: "Pengajuan Keberatan",
+		icon: "icon-notebook",
+		translate: "sidebar.nav.PENGAJUAN_KEBERATAN",
+		submenu: [
+			{
+				name: "a. Permohonan Keberatan",
+				path: "/app/pt/keberatan",
+			},
+			{
+				name: "b. Jawaban atas permohonan keberatan",
+				path: "/app/pt/jawaban-keberatan",
+			},
+			{
+				name: "c. Jawaban atas permohonan banding",
+				path: "/app/pt/jawaban-banding",
+			},
+		],
+	},
+	{
+		name: "Dokumen Perbaikan",
+		path: "/app/pt/dokumen-perbaikan",
+		icon: "icon-notebook",
+		translate: "sidebar.nav.PT_DOKUMEN_PERBAIKAN",
+	},
+	{
+		name: "Permohonan Pencabutan Sanksi",
+		path: "/app/pt/pencabutan-sanksi",
+		icon: "icon-notebook",
+		translate: "sidebar.nav.PT_PENCABUTAN_SANKSI",
+	},
+	{
+		name: "Jawaban Permohonan Pencabutan Sanksi",
+		path: "/app/pt/jawaban-pencabutan-sanksi",
+		icon: "icon-notebook",
+		translate: "sidebar.nav.PT_JAWABAN_PENCABUTAN_SANKSI",
+	},
+];
+
+export default MenuPT;
+``;

+ 273 - 318
components/Layout/Sidebar.js

@@ -1,103 +1,100 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { withTranslation, Trans } from '@/components/Common/Translate';
-import Link from 'next/link';
-import Router, { withRouter } from 'next/router';
-import { Collapse, Badge } from 'reactstrap';
+import React, { Component } from "react";
+import PropTypes from "prop-types";
+import { withTranslation, Trans } from "@/components/Common/Translate";
+import Link from "next/link";
+import Router, { withRouter } from "next/router";
+import { Collapse, Badge } from "reactstrap";
 
-import { connect } from 'react-redux';
-import { bindActionCreators } from 'redux';
-import * as actions from '../../store/actions/actions';
+import { connect } from "react-redux";
+import { bindActionCreators } from "redux";
+import * as actions from "../../store/actions/actions";
 
-import SidebarUserBlock from './SidebarUserBlock';
+import SidebarUserBlock from "./SidebarUserBlock";
 
-import Menu from './Menu.js';
+import Menu from "./Menu.js";
+import MenuPT from "./MenuPT.js";
+// localStorage.getItem("user");
+// import Menu from './MenuPT.js';
 
 // Helper to check for parrent of an given elements
 const parents = (element, selector) => {
-    if (typeof selector !== 'string') {
-        return null;
-    }
-
-    const parents = [];
-    let ancestor = element.parentNode;
-
-    while (
-        ancestor &&
-        ancestor.nodeType === Node.ELEMENT_NODE &&
-        ancestor.nodeType !== 3 /*NODE_TEXT*/
-    ) {
-        if (ancestor.matches(selector)) {
-            parents.push(ancestor);
-        }
-
-        ancestor = ancestor.parentNode;
-    }
-    return parents;
+	if (typeof selector !== "string") {
+		return null;
+	}
+
+	const parents = [];
+	let ancestor = element.parentNode;
+
+	while (ancestor && ancestor.nodeType === Node.ELEMENT_NODE && ancestor.nodeType !== 3 /*NODE_TEXT*/) {
+		if (ancestor.matches(selector)) {
+			parents.push(ancestor);
+		}
+
+		ancestor = ancestor.parentNode;
+	}
+	return parents;
 };
 // Helper to get outerHeight of a dom element
 const outerHeight = (elem, includeMargin) => {
-    const style = getComputedStyle(elem);
-    const margins = includeMargin
-        ? parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10)
-        : 0;
-    return elem.offsetHeight + margins;
+	const style = getComputedStyle(elem);
+	const margins = includeMargin ? parseInt(style.marginTop, 10) + parseInt(style.marginBottom, 10) : 0;
+	return elem.offsetHeight + margins;
 };
 
 /**
     Component to display headings on sidebar
 */
 const SidebarItemHeader = ({ item }) => (
-    <li className="nav-heading">
-        <span>
-            <Trans i18nKey={item.translate}>{item.heading}</Trans>
-        </span>
-    </li>
+	<li className="nav-heading">
+		<span>
+			<Trans i18nKey={item.translate}>{item.heading}</Trans>
+		</span>
+	</li>
 );
 
 /**
     Normal items for the sidebar
 */
 const SidebarItem = ({ item, isActive, className, onMouseEnter }) => (
-    <li className={isActive ? 'active' : ''} onMouseEnter={onMouseEnter}>
-        <Link href={item.path} as={item.as}>
-            <a title={item.name}>
-                {item.label && (
-                    <Badge tag="div" className="float-right" color={item.label.color}>
-                        {item.label.value}
-                    </Badge>
-                )}
-                {item.icon && <em className={item.icon} />}
-                <span>
-                    <Trans i18nKey={item.translate}>{item.name}</Trans>
-                </span>
-            </a>
-        </Link>
-    </li>
+	<li className={isActive ? "active" : ""} onMouseEnter={onMouseEnter}>
+		<Link href={item.path} as={item.as}>
+			<a title={item.name}>
+				{item.label && (
+					<Badge tag="div" className="float-right" color={item.label.color}>
+						{item.label.value}
+					</Badge>
+				)}
+				{item.icon && <em className={item.icon} />}
+				<span>
+					<Trans i18nKey={item.translate}>{item.name}</Trans>
+				</span>
+			</a>
+		</Link>
+	</li>
 );
 
 /**
     Build a sub menu with items inside and attach collapse behavior
 */
 const SidebarSubItem = ({ item, isActive, handler, children, isOpen, onMouseEnter }) => (
-    <li className={isActive ? 'active' : ''}>
-        <div className="nav-item" onClick={handler} onMouseEnter={onMouseEnter}>
-            {item.label && (
-                <Badge tag="div" className="float-right" color={item.label.color}>
-                    {item.label.value}
-                </Badge>
-            )}
-            {item.icon && <em className={item.icon} />}
-            <span>
-                <Trans i18nKey={item.translate}>{item.name}</Trans>
-            </span>
-        </div>
-        <Collapse isOpen={isOpen}>
-            <ul id={item.path} className="sidebar-nav sidebar-subnav">
-                {children}
-            </ul>
-        </Collapse>
-    </li>
+	<li className={isActive ? "active" : ""}>
+		<div className="nav-item" onClick={handler} onMouseEnter={onMouseEnter}>
+			{item.label && (
+				<Badge tag="div" className="float-right" color={item.label.color}>
+					{item.label.value}
+				</Badge>
+			)}
+			{item.icon && <em className={item.icon} />}
+			<span>
+				<Trans i18nKey={item.translate}>{item.name}</Trans>
+			</span>
+		</div>
+		<Collapse isOpen={isOpen}>
+			<ul id={item.path} className="sidebar-nav sidebar-subnav">
+				{children}
+			</ul>
+		</Collapse>
+	</li>
 );
 
 /**
@@ -105,263 +102,221 @@ const SidebarSubItem = ({ item, isActive, handler, children, isOpen, onMouseEnte
 */
 const SidebarSubHeader = ({ item }) => <li className="sidebar-subnav-header">{item.name}</li>;
 
-const SidebarBackdrop = ({ closeFloatingNav }) => (
-    <div className="sidebar-backdrop" onClick={closeFloatingNav} />
-);
+const SidebarBackdrop = ({ closeFloatingNav }) => <div className="sidebar-backdrop" onClick={closeFloatingNav} />;
 
 const FloatingNav = ({ item, target, routeActive, isFixed, closeFloatingNav }) => {
-    let asideContainer = document.querySelector('.aside-container');
-    let asideInner = asideContainer.firstElementChild; /*('.aside-inner')*/
-    let sidebar = asideInner.firstElementChild; /*('.sidebar')*/
-
-    let mar =
-        parseInt(getComputedStyle(asideInner)['padding-top'], 0) +
-        parseInt(getComputedStyle(asideContainer)['padding-top'], 0);
-    let itemTop = target.parentElement.offsetTop + mar - sidebar.scrollTop;
-    let vwHeight = document.body.clientHeight;
-
-    const setPositionStyle = el => {
-        if (!el) return;
-        el.style.position = isFixed ? 'fixed' : 'absolute';
-        el.style.top = itemTop + 'px';
-        el.style.bottom = outerHeight(el, true) + itemTop > vwHeight ? 0 : 'auto';
-    };
-
-    return (
-        <ul
-            id={item.path}
-            ref={setPositionStyle}
-            className="sidebar-nav sidebar-subnav nav-floating"
-            onMouseLeave={closeFloatingNav}
-        >
-            <SidebarSubHeader item={item} />
-            {item.submenu.map((subitem, i) => (
-                <SidebarItem key={i} item={subitem} isActive={routeActive(subitem.path)} />
-            ))}
-        </ul>
-    );
+	let asideContainer = document.querySelector(".aside-container");
+	let asideInner = asideContainer.firstElementChild; /*('.aside-inner')*/
+	let sidebar = asideInner.firstElementChild; /*('.sidebar')*/
+
+	let mar = parseInt(getComputedStyle(asideInner)["padding-top"], 0) + parseInt(getComputedStyle(asideContainer)["padding-top"], 0);
+	let itemTop = target.parentElement.offsetTop + mar - sidebar.scrollTop;
+	let vwHeight = document.body.clientHeight;
+
+	const setPositionStyle = (el) => {
+		if (!el) return;
+		el.style.position = isFixed ? "fixed" : "absolute";
+		el.style.top = itemTop + "px";
+		el.style.bottom = outerHeight(el, true) + itemTop > vwHeight ? 0 : "auto";
+	};
+
+	return (
+		<ul id={item.path} ref={setPositionStyle} className="sidebar-nav sidebar-subnav nav-floating" onMouseLeave={closeFloatingNav}>
+			<SidebarSubHeader item={item} />
+			{item.submenu.map((subitem, i) => (
+				<SidebarItem key={i} item={subitem} isActive={routeActive(subitem.path)} />
+			))}
+		</ul>
+	);
 };
 
 /**
     The main sidebar component
 */
 class Sidebar extends Component {
-    state = {
-        collapse: {},
-        showSidebarBackdrop: false,
-        currentFloatingItem: null,
-        currentFloatingItemTarget: null,
-        pathname: this.props.router.pathname
-    };
-
-    componentDidMount() {
-        // prepare the flags to handle menu collapsed states
-        this.buildCollapseList();
-
-        // Listen for routes changes in order to hide the sidebar on mobile
-        Router.events.on('routeChangeStart', this.handleRouteChange);
-        Router.events.on('routeChangeComplete', this.handleRouteComplete);
-
-        // Attach event listener to automatically close sidebar when click outside
-        document.addEventListener('click', this.closeSidebarOnExternalClicks);
-    }
-
-    handleRouteComplete = (pathname) => {
-        this.setState({
-            pathname
-        })
-    }
-
-    handleRouteChange = () => {
-        this.closeFloatingNav();
-        this.closeSidebar();
-    };
-
-    componentWillUnmount() {
-        document.removeEventListener('click', this.closeSidebarOnExternalClicks);
-        Router.events.off('routeChangeStart', this.handleRouteChange);
-        Router.events.off('routeChangeComplete', this.handleRouteComplete);
-    }
-
-    closeSidebar = () => {
-        this.props.actions.toggleSetting('asideToggled');
-    };
-
-    closeSidebarOnExternalClicks = e => {
-        // don't check if sidebar not visible
-        if (!this.props.settings.asideToggled) return;
-
-        if (
-            !parents(e.target, '.aside-container').length && // if not child of sidebar
-            !parents(e.target, '.topnavbar-wrapper').length && // if not child of header
-            !e.target.matches('#user-block-toggle') && // user block toggle anchor
-            !e.target.parentElement.matches('#user-block-toggle') // user block toggle icon
-        ) {
-            this.closeSidebar();
-        }
-    };
-
-    /** prepare initial state of collapse menus.*/
-    buildCollapseList = () => {
-        let collapse = {};
-        Menu.filter(({ heading }) => !heading).forEach(({ name, path, submenu }) => {
-            collapse[name] = this.routeActive(submenu ? submenu.map(({ path }) => path) : path);
-        });
-        this.setState({ collapse });
-    };
-
-    routeActive = paths => {
-        const currpath = this.state.pathname;
-        paths = Array.isArray(paths) ? paths : [paths];
-        return paths.some(p => (p === '/' ? currpath === p : currpath.indexOf(p) > -1));
-    };
-
-    toggleItemCollapse = stateName => () => {
-        for (let c in this.state.collapse) {
-            if (this.state.collapse[c] === true && c !== stateName)
-                this.setState({
-                    collapse: {
-                        [c]: false
-                    }
-                });
-        }
-        this.setState({
-            collapse: {
-                [stateName]: !this.state.collapse[stateName]
-            }
-        });
-    };
-
-    getSubRoutes = item => item.submenu.map(({ path }) => path);
-
-    /** map menu config to string to determine which element to render */
-    itemType = item => {
-        if (item.heading) return 'heading';
-        if (!item.submenu) return 'menu';
-        if (item.submenu) return 'submenu';
-    };
-
-    shouldUseFloatingNav = () => {
-        return (
-            this.props.settings.isCollapsed ||
-            this.props.settings.isCollapsedText ||
-            this.props.settings.asideHover
-        );
-    };
-
-    showFloatingNav = item => e => {
-        if (this.shouldUseFloatingNav())
-            this.setState({
-                currentFloatingItem: item,
-                currentFloatingItemTarget: e.currentTarget,
-                showSidebarBackdrop: true
-            });
-    };
-
-    closeFloatingNav = () => {
-        this.setState({
-            currentFloatingItem: null,
-            currentFloatingItemTarget: null,
-            showSidebarBackdrop: false
-        });
-    };
-
-    render() {
-        return (
-            <>
-                <aside className="aside-container">
-                    {/* START Sidebar (left) */}
-                    <div className="aside-inner">
-                        <nav
-                            className={
-                                'sidebar ' +
-                                (this.props.settings.asideScrollbar ? 'show-scrollbar' : '')
-                            }
-                        >
-                            {/* START sidebar nav */}
-                            <ul className="sidebar-nav">
-                                {/* START user info */}
-                                <li className="has-user-block">
-                                    <SidebarUserBlock />
-                                </li>
-                                {/* END user info */}
-
-                                {/* Iterates over all sidebar items */}
-                                {Menu.map((item, i) => {
-                                    // heading
-                                    if (this.itemType(item) === 'heading')
-                                        return <SidebarItemHeader item={item} key={i} />;
-                                    else {
-                                        if (this.itemType(item) === 'menu')
-                                            return (
-                                                <SidebarItem
-                                                    isActive={this.routeActive(item.path)}
-                                                    item={item}
-                                                    key={i}
-                                                    onMouseEnter={this.closeFloatingNav}
-                                                />
-                                            );
-                                        if (this.itemType(item) === 'submenu')
-                                            return [
-                                                <SidebarSubItem
-                                                    item={item}
-                                                    isOpen={this.state.collapse[item.name]}
-                                                    handler={this.toggleItemCollapse(item.name)}
-                                                    isActive={this.routeActive(
-                                                        this.getSubRoutes(item)
-                                                    )}
-                                                    key={i}
-                                                    onMouseEnter={this.showFloatingNav(item)}
-                                                >
-                                                    <SidebarSubHeader item={item} key={i} />
-                                                    {item.submenu.map((subitem, i) => (
-                                                        <SidebarItem
-                                                            key={i}
-                                                            item={subitem}
-                                                            isActive={this.routeActive(
-                                                                subitem.path
-                                                            )}
-                                                        />
-                                                    ))}
-                                                </SidebarSubItem>
-                                            ];
-                                    }
-                                    return null; // unrecognized item
-                                })}
-                            </ul>
-                            {/* END sidebar nav */}
-                        </nav>
-                    </div>
-                    {/* END Sidebar (left) */}
-                    {this.state.currentFloatingItem && this.state.currentFloatingItem.submenu && (
-                        <FloatingNav
-                            item={this.state.currentFloatingItem}
-                            target={this.state.currentFloatingItemTarget}
-                            routeActive={this.routeActive}
-                            isFixed={this.props.settings.isFixed}
-                            closeFloatingNav={this.closeFloatingNav}
-                        />
-                    )}
-                </aside>
-                {this.state.showSidebarBackdrop && (
-                    <SidebarBackdrop closeFloatingNav={this.closeFloatingNav} />
-                )}
-            </>
-        );
-    }
+	menu = [];
+	state = {
+		collapse: {},
+		showSidebarBackdrop: false,
+		currentFloatingItem: null,
+		currentFloatingItemTarget: null,
+		pathname: this.props.router.pathname,
+	};
+
+	componentDidMount() {
+		this.menu = JSON.parse(sessionStorage.getItem("user")).peran[0].peran.id === 2 ? MenuPT : Menu;
+		// prepare the flags to handle menu collapsed states
+		this.buildCollapseList();
+
+		// Listen for routes changes in order to hide the sidebar on mobile
+		Router.events.on("routeChangeStart", this.handleRouteChange);
+		Router.events.on("routeChangeComplete", this.handleRouteComplete);
+
+		// Attach event listener to automatically close sidebar when click outside
+		document.addEventListener("click", this.closeSidebarOnExternalClicks);
+	}
+
+	handleRouteComplete = (pathname) => {
+		this.setState({
+			pathname,
+		});
+	};
+
+	handleRouteChange = () => {
+		this.closeFloatingNav();
+		this.closeSidebar();
+	};
+
+	componentWillUnmount() {
+		document.removeEventListener("click", this.closeSidebarOnExternalClicks);
+		Router.events.off("routeChangeStart", this.handleRouteChange);
+		Router.events.off("routeChangeComplete", this.handleRouteComplete);
+	}
+
+	closeSidebar = () => {
+		this.props.actions.toggleSetting("asideToggled");
+	};
+
+	closeSidebarOnExternalClicks = (e) => {
+		// don't check if sidebar not visible
+		if (!this.props.settings.asideToggled) return;
+
+		if (
+			!parents(e.target, ".aside-container").length && // if not child of sidebar
+			!parents(e.target, ".topnavbar-wrapper").length && // if not child of header
+			!e.target.matches("#user-block-toggle") && // user block toggle anchor
+			!e.target.parentElement.matches("#user-block-toggle") // user block toggle icon
+		) {
+			this.closeSidebar();
+		}
+	};
+
+	/** prepare initial state of collapse menus.*/
+	buildCollapseList = () => {
+		let collapse = {};
+		this.menu
+			.filter(({ heading }) => !heading)
+			.forEach(({ name, path, submenu }) => {
+				collapse[name] = this.routeActive(submenu ? submenu.map(({ path }) => path) : path);
+			});
+		this.setState({ collapse });
+	};
+
+	routeActive = (paths) => {
+		const currpath = this.state.pathname;
+		paths = Array.isArray(paths) ? paths : [paths];
+		return paths.some((p) => (p === "/" ? currpath === p : currpath.indexOf(p) > -1));
+	};
+
+	toggleItemCollapse = (stateName) => () => {
+		for (let c in this.state.collapse) {
+			if (this.state.collapse[c] === true && c !== stateName)
+				this.setState({
+					collapse: {
+						[c]: false,
+					},
+				});
+		}
+		this.setState({
+			collapse: {
+				[stateName]: !this.state.collapse[stateName],
+			},
+		});
+	};
+
+	getSubRoutes = (item) => item.submenu.map(({ path }) => path);
+
+	/** map menu config to string to determine which element to render */
+	itemType = (item) => {
+		if (item.heading) return "heading";
+		if (!item.submenu) return "menu";
+		if (item.submenu) return "submenu";
+	};
+
+	shouldUseFloatingNav = () => {
+		return this.props.settings.isCollapsed || this.props.settings.isCollapsedText || this.props.settings.asideHover;
+	};
+
+	showFloatingNav = (item) => (e) => {
+		if (this.shouldUseFloatingNav())
+			this.setState({
+				currentFloatingItem: item,
+				currentFloatingItemTarget: e.currentTarget,
+				showSidebarBackdrop: true,
+			});
+	};
+
+	closeFloatingNav = () => {
+		this.setState({
+			currentFloatingItem: null,
+			currentFloatingItemTarget: null,
+			showSidebarBackdrop: false,
+		});
+	};
+
+	render() {
+		return (
+			<>
+				<aside className="aside-container">
+					{/* START Sidebar (left) */}
+					<div className="aside-inner">
+						<nav className={"sidebar " + (this.props.settings.asideScrollbar ? "show-scrollbar" : "")}>
+							{/* START sidebar nav */}
+							<ul className="sidebar-nav">
+								{/* START user info */}
+								<li className="has-user-block">
+									<SidebarUserBlock />
+								</li>
+								{/* END user info */}
+
+								{/* Iterates over all sidebar items */}
+								{this.menu.map((item, i) => {
+									// heading
+									if (this.itemType(item) === "heading") return <SidebarItemHeader item={item} key={i} />;
+									else {
+										if (this.itemType(item) === "menu") return <SidebarItem isActive={this.routeActive(item.path)} item={item} key={i} onMouseEnter={this.closeFloatingNav} />;
+										if (this.itemType(item) === "submenu")
+											return [
+												<SidebarSubItem
+													item={item}
+													isOpen={this.state.collapse[item.name]}
+													handler={this.toggleItemCollapse(item.name)}
+													isActive={this.routeActive(this.getSubRoutes(item))}
+													key={i}
+													onMouseEnter={this.showFloatingNav(item)}
+												>
+													<SidebarSubHeader item={item} key={i} />
+													{item.submenu.map((subitem, i) => (
+														<SidebarItem key={i} item={subitem} isActive={this.routeActive(subitem.path)} />
+													))}
+												</SidebarSubItem>,
+											];
+									}
+									return null; // unrecognized item
+								})}
+							</ul>
+							{/* END sidebar nav */}
+						</nav>
+					</div>
+					{/* END Sidebar (left) */}
+					{this.state.currentFloatingItem && this.state.currentFloatingItem.submenu && (
+						<FloatingNav item={this.state.currentFloatingItem} target={this.state.currentFloatingItemTarget} routeActive={this.routeActive} isFixed={this.props.settings.isFixed} closeFloatingNav={this.closeFloatingNav} />
+					)}
+				</aside>
+				{this.state.showSidebarBackdrop && <SidebarBackdrop closeFloatingNav={this.closeFloatingNav} />}
+			</>
+		);
+	}
 }
 
 Sidebar.propTypes = {
-    actions: PropTypes.object,
-    settings: PropTypes.object
+	actions: PropTypes.object,
+	settings: PropTypes.object,
 };
 
-const mapStateToProps = state => ({ settings: state.settings });
-const mapDispatchToProps = dispatch => ({
-    actions: bindActionCreators(actions, dispatch)
+const mapStateToProps = (state) => ({ settings: state.settings });
+const mapDispatchToProps = (dispatch) => ({
+	actions: bindActionCreators(actions, dispatch),
 });
 
-export default connect(
-    mapStateToProps,
-    mapDispatchToProps
-)(withRouter(withTranslation(Sidebar)));
+export default connect(mapStateToProps, mapDispatchToProps)(withRouter(withTranslation(Sidebar)));

+ 45 - 42
components/Layout/SidebarUserBlock.js

@@ -1,51 +1,54 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { Collapse } from 'reactstrap';
+import React, { Component } from "react";
+import PropTypes from "prop-types";
+import { Collapse } from "reactstrap";
 
-import { connect } from 'react-redux';
+import { connect } from "react-redux";
 
 class SidebarUserBlock extends Component {
-
-    state = {
-        showUserBlock: false
-    }
-
-    componentDidUpdate(oldProps) {
-        if (oldProps.showUserBlock !== this.props.showUserBlock) {
-            this.setState({ showUserBlock: this.props.showUserBlock })
-        }
-    }
-
-    render() {
-        return (
-            <Collapse id="user-block" isOpen={ this.state.showUserBlock }>
-                <div>
-                    <div className="item user-block">
-                       {/* User picture */}
-                       <div className="user-block-picture">
-                          <div className="user-block-status">
-                             <img className="img-thumbnail rounded-circle" src="/static/img/user/02.jpg" alt="Avatar" width="60" height="60" />
-                             <div className="circle bg-success circle-lg"></div>
-                          </div>
-                       </div>
-                       {/* Name and Job */}
-                       <div className="user-block-info">
-                          <span className="user-block-name">Hello, Mike</span>
-                          <span className="user-block-role">Designer</span>
-                       </div>
-                    </div>
-                </div>
-            </Collapse>
-        )
-    }
+	state = {
+		showUserBlock: true,
+		user: {},
+	};
+
+	componentDidMount() {
+		this.setState({ user: JSON.parse(sessionStorage.getItem("user")) });
+	}
+
+	componentDidUpdate(oldProps) {
+		if (oldProps.showUserBlock !== this.props.showUserBlock) {
+			this.setState({ showUserBlock: this.props.showUserBlock });
+		}
+	}
+
+	render() {
+		const { user } = this.state;
+		return (
+			<Collapse id="user-block" isOpen={this.state.showUserBlock}>
+				<div>
+					<div className="item user-block">
+						{/* User picture */}
+						<div className="user-block-picture">
+							<div className="user-block-status">
+								<img className="img-thumbnail rounded-circle" src="/static/img/logo-single.png" alt="Avatar" width="60" height="60" />
+								<div className="circle bg-success circle-lg"></div>
+							</div>
+						</div>
+						{/* Name and Job */}
+						<div className="user-block-info">
+							<span className="user-block-name">{user.nama}</span>
+							{/* <span className="user-block-role">{user.nama}</span> */}
+						</div>
+					</div>
+				</div>
+			</Collapse>
+		);
+	}
 }
 
 SidebarUserBlock.propTypes = {
-    showUserBlock: PropTypes.bool
+	showUserBlock: PropTypes.bool,
 };
 
-const mapStateToProps = state => ({ showUserBlock: state.settings.showUserBlock })
+const mapStateToProps = (state) => ({ showUserBlock: state.settings.showUserBlock });
 
-export default connect(
-    mapStateToProps
-)(SidebarUserBlock);
+export default connect(mapStateToProps)(SidebarUserBlock);

+ 3 - 3
json/dataUser.js

@@ -2,7 +2,7 @@ module.exports = [
 	{
 		id: "2A080F42-AE7F-407B-976E-DE5FA87BD277",
 		username: "dikti",
-        password: "123",
+		password: "123",
 		nama: "Dikti Ristek/LLDIKTI",
 		no_telp: "0211111222233",
 		no_hp: "197903302008011007",
@@ -29,7 +29,7 @@ module.exports = [
 	{
 		id: "2A080F42-AE7F-407B-976E-DE5FA87BD278",
 		username: "satyagama",
-        password: "123",
+		password: "123",
 		nama: "Univertisa Satyagama",
 		no_telp: "02157946063",
 		no_hp: "197903302008011007",
@@ -38,7 +38,7 @@ module.exports = [
 		id_sdm_pengguna: null,
 		peran: [
 			{
-				id: "96EBA4CC-5DE1-4429-A836-56E32A63FC67",
+				id: "96EBA4CC-5DE1-4429-A836-56E32A63FC69",
 				organisasi: {
 					id: "86942CDF-44F1-446E-8E9E-CB37BBBB16E6",
 					nama: "Semua Unit",

+ 8 - 0
pages/app/_middleware.js

@@ -0,0 +1,8 @@
+import { NextResponse, NextRequest } from "next/server";
+
+export async function middleware(req, ev) {
+	if (!req.session.user) {
+		return NextResponse.redirect("/login");
+	}
+	return NextResponse.next();
+}

+ 19 - 14
pages/login.js

@@ -1,12 +1,11 @@
 import { connect } from "react-redux";
-// import Router, { withRouter } from "next/router";
 import { login } from "@/store/actions/user";
 
 import dataUser from "../json/dataUser";
 import React, { Component } from "react";
 import BasePage from "@/components/Layout/BasePage";
-import { Row, Col, Input, Card, CardHeader, CardBody, CardFooter, CustomInput } from "reactstrap";
-
+import { Row, Col, Input, Card, CardHeader, CardBody, Button, CardFooter, CustomInput } from "reactstrap";
+import Router from "next/router";
 import FormValidator from "@/components/Forms/Validator.js";
 
 class Login extends Component {
@@ -58,17 +57,23 @@ class Login extends Component {
 		});
 
 		console.log(hasError ? "Form has errors. Check!" : "Form Submitted!");
+		e.preventDefault();
 		if (!hasError) {
 			const { username, password } = this.state.formLogin;
 			let user = dataUser.filter((e) => e.username === username && e.password === password);
 			if (user.length) {
 				user = user[0];
-				console.log(user);
-			}
-			this.dispatch(login(username, password));
 
-			e.preventDefault();
+				sessionStorage.setItem("user", JSON.stringify(user));
+				if (JSON.parse(sessionStorage.getItem("user")).peran[0].peran.id === 2) {
+					Router.push({ pathname: "/app/pt/pemantauan" });
+				} else {
+					Router.push({ pathname: "/app/pemantauan" });
+				}
+			}
+			// this.dispatch(login(username, password));
 		}
+		// e.preventDefault();
 	};
 
 	/* Simplify error check */
@@ -79,9 +84,9 @@ class Login extends Component {
 	render() {
 		return (
 			<div className="block-center mt-4 wd-xl">
-				<div className="card card-flat">
-					<img className="card-img-top" src="/static/img/logo.png" alt="Logo"></img>
-					<div className="card-body">
+				<Card className="card card-flat">
+					<img className="card-img-top" src="/static/img/logo.png" alt="Logo" />
+					<CardBody className="card-body">
 						{" "}
 						<h5 className="card-title text-center py-2 bg-gray">Aplikasi Perguruan Tinggi Bermasalah </h5>
 						<form onSubmit={this.onSubmit} method="post" name="formLogin">
@@ -104,12 +109,12 @@ class Login extends Component {
 								<span className="invalid-feedback">Field is required</span>
 							</div>
 							<div className="required">* Required fields</div>
-							<button type="submit" className="btn btn-block btn-primary mt-3">
+							<Button color="primary" type="submit" block className=" mt-3">
 								Login
-							</button>
+							</Button>
 						</form>
-					</div>
-				</div>
+					</CardBody>
+				</Card>
 			</div>
 		);
 	}

+ 1 - 0
pages/logout.js

@@ -0,0 +1 @@
+

+ 0 - 58
pages/singleview.js

@@ -1,58 +0,0 @@
-import React from 'react';
-import { Trans } from '@/components/Common/Translate';
-import ContentWrapper from '@/components/Layout/ContentWrapper';
-import { Row, Col, Dropdown, DropdownToggle, DropdownMenu, DropdownItem } from 'reactstrap';
-
-class SingleView extends React.Component {
-
-    state = {
-      dropdownOpen: false
-    }
-
-    changeLanguage = lng => {
-        this.props.changeLanguage(lng);
-    }
-
-    toggle = () => {
-        this.setState({
-            dropdownOpen: !this.state.dropdownOpen
-        });
-    }
-
-    render() {
-        return (
-            <ContentWrapper>
-                <div className="content-heading">
-                   <div>Single View
-                      <small><Trans i18nKey='dashboard.WELCOME'></Trans></small>
-                   </div>
-                    { /* START Language list */ }
-                    <div className="ml-auto">
-                        <Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
-                            <DropdownToggle>
-                                English
-                            </DropdownToggle>
-                            <DropdownMenu className="dropdown-menu-right-forced animated fadeInUpShort">
-                                <DropdownItem onClick={() => this.changeLanguage('en')}>English</DropdownItem>
-                                <DropdownItem onClick={() => this.changeLanguage('es')}>Spanish</DropdownItem>
-                            </DropdownMenu>
-                        </Dropdown>
-                    </div>
-                    { /* END Language list */ }
-                </div>
-                <Row>
-                    <Col xs={12} className="text-center">
-                        <h2 className="text-thin">Single view content</h2>
-                        <p>
-                            This project is an application skeleton. You can use it to quickly bootstrap your ReactJS webapp projects and dev environment for these projects.
-                            <br/>
-                            The seed app doesn't do much and has most of the feature removed so you can add theme as per your needs just following the demo app examples.
-                        </p>
-                    </Col>
-                </Row>
-            </ContentWrapper>
-        );
-    }
-}
-
-export default SingleView;

+ 3 - 4
store/actions/user.js

@@ -5,9 +5,8 @@ import dataUser from "@/json/dataUser";
 
 export const login = (username, password) => (dispatch) => {
 	let data = dataUser.filter((value) => value.username === username && value.password === password);
-	if (!data.length) {
-		return dispatch({ type: LOGIN_FAIL });
-	}
+	if (!data.length) dispatch({ type: LOGIN_FAIL });
 	data = data[0];
-	return dispatch({ type: LOGIN_SUCCESS, payload: data });
+	localStorage.setItem("userInfo", JSON.stringify(data));
+	dispatch({ type: LOGIN_SUCCESS, payload: data });
 };