React problem with AdminLTE3 sidebar treeview - javascript

So I want to make a React sidebar with an item 'Employee' that when clicked will expand three child items.
Here is the code
import React, { Component } from "react";
export default class Sidebar extends Component {
constructor(props) {
super(props);
this.state = {
user: {}
}
}
componentDidMount() {
let userData = JSON.parse(localStorage.getItem('user'))
this.setState({user: userData})
}
render() {
return (
<aside className="main-sidebar sidebar-dark-primary elevation-4" >
{/* Brand Logo */}
<a href="/" className="brand-link">
<span className="brand-text font-weight-light ml-1">HRMS</span>
</a>
{/* Sidebar */}
<div className="sidebar">
{/* Sidebar user panel (optional) */}
<div className="user-panel mt-3 pb-3 mb-3 d-flex">
<div className="image">
<img
src={process.env.PUBLIC_URL + '/dist/img/user2-160x160.jpg'}
className="img-circle elevation-2"
alt="User Image"
/>
</div>
<div className="info">
<a href="#" className="d-block">
{this.state.user.fullname}
</a>
</div>
</div>
{/* Sidebar Menu */}
<nav className="mt-2">
<ul
className="nav nav-pills nav-sidebar flex-column"
data-widget="treeview"
role="menu"
data-accordion="false"
>
{/* Add icons to the links using the .nav-icon class
with font-awesome or any other icon font library */}
<li className="nav-item">
<a href="/" className="nav-link active">
<i className="nav-icon fas fa-tachometer-alt" />
<p>
Dashboard
<span className="right badge badge-success">Home</span>
</p>
</a>
</li>
<li className="nav-item">
<a href="pages/widgets.html" className="nav-link">
<i className="nav-icon fas fa-th" />
<p>
Widgets
<span className="right badge badge-danger">New</span>
</p>
</a>
</li>
<li className="nav-item has-treeview">
<a href="#" className="nav-link">
<i className="nav-icon fa fa-user" />
<p>
Employee
<i className="right fas fa-angle-left" />
</p>
</a>
<ul className="nav nav-treeview">
<li className="nav-item">
<a href="/employee-add" className="nav-link">
<i className="fa fa-user-plus nav-icon" />
<p>Add Employee</p>
</a>
</li>
<li className="nav-item">
<a href="/employee-list" className="nav-link">
<i className="fas fa-users nav-icon" />
<p>Employee List</p>
</a>
</li>
<li className="nav-item">
<a href="/employee-add" className="nav-link">
<i className="far fa-circle nav-icon" />
<p>Employee Award</p>
</a>
</li>
</ul>
</li>
The problem is after login redirects to this page and I click the Employee item, the href activates and just reloads the page (what href="#" usually does). However if i remove the <i></i> tag or the href the css gets all messed up.
I am using AdminLTE3 so here is the documentation: https://adminlte.io/docs/3.0/javascript/treeview.html

I found the answer as it is a problem to many people. The problem occurs when you redirect from another page (i.e login page)
Here is the link to the answer: https://github.com/ColorlibHQ/AdminLTE/issues/1570#issuecomment-615841382

Try This
index.html
add this code to the script after body tag
<script>
$(document).ready(function(){
$('.nav-item ').click(function(){
if($(this).hasClass('menu-open')){
$(this).removeClass("menu-open");
$(this).children().removeClass("active");
}else{
$(this).addClass("menu-open");
$(this).children().addClass("active");
}
$('.nav-item').children().removeClass('active').not(this);
$(this).children().addClass("active");
});
});
</script>

Related

Combine Topbar and Sidebar into single "Nav" layout - ReactJS

I am building a react app that renders 2 layouts, a layout without the sidebar nav and topbar when you are not logged in, and then a different layout that does render the topbar and sidebar nav when you are logged in (through a context).
The issue that I am facing is that when logged in, the topbar and sidebar nav render as separate components and any other component that I wish to display ends up all the way at the bottom - see these images for context Pic1 Pic 2
As you can see, everything renders top down ("Dashboard" is an example of a component that I would like rendered next to and below the sidebar and topbar. What I would like to do is render the topbar and sidebar as a single component, and then render any other page components in that large white space. Perhaps there is a way to combine the two bars into a single layout?
I will share some code below...
Topbar.jsx
import "startbootstrap-sb-admin-2-master/css/sb-admin-2.min.css";
import { useAuth } from "../../hooks/auth";
export const TopBar = () => {
const user = useAuth().user;
const { logout } = useAuth();
const handleSubmit = async (e) => {
e.preventDefault();
logout();
};
return (
<div id="content-wrapper" className="d-flex flex-column">
<div id="content">
<div className="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
<button
id="sidebarToggleTop"
className="btn btn-link d-md-none rounded-circle mr-3"
>
<i className="fa fa-bars"></i>
</button>
<form className="d-none d-sm-inline-block form-inline mr-auto ml-md-3 my-2 my-md-0 mw-100 navbar-search">
<div className="input-group">
<input
type="text"
className="form-control bg-light border-0 small"
placeholder="Search for..."
aria-label="Search"
aria-describedby="basic-addon2"
/>
<div className="input-group-append">
<button className="btn btn-primary" type="button">
<i className="fa-solid fa-magnifying-glass"></i>
</button>
</div>
</div>
</form>
<ul className="navbar-nav ml-auto">
<li className="nav-item dropdown no-arrow mx-1">
<div
className="nav-link dropdown-toggle"
href="#"
id="alertsDropdown"
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<i className="fas fa-bell fa-fw"></i>
<span className="badge badge-danger badge-counter">3+</span>
</div>
</li>
<div className="topbar-divider d-none d-sm-block" />
<li className="nav-item dropdown no-arrow">
<div
className="nav-link"
id="userDropdown"
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<text className="mr-2 d-none d-lg-inline text-gray-600 small">
Hi, {user}!
</text>
<i className="fa-solid fa-user"></i>
</div>
</li>
<li className="nav-item dropdown no-arrow">
<div
className="nav-link"
id="userDropdown"
role="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
>
<button
className="btn btn-secondary btn-circle"
type="button"
onClick={handleSubmit}
>
<i className="fa-solid fa-arrow-right-from-bracket"></i>
</button>
</div>
</li>
</ul>
</div>
</div>
</div>
);
};
Navbar.jsx (sidebar)
import "startbootstrap-sb-admin-2-master/css/sb-admin-2.min.css";
import { useAuth } from "../../hooks/auth";
export const Navbar = () => {
return (
<div id="wrapper">
<ul
className="navbar-nav bg-gradient-primary sidebar sidebar-dark accordion"
id="accordionSidebar"
>
<hr className="sidebar-divider my-0" />
<li className="nav-item active">
<a className="nav-link" href="index.html">
<i className="fas fa-fw fa-tachometer-alt"></i>
<span>Dashboard</span>
</a>
</li>
<hr className="sidebar-divider" />
<div className="sidebar-heading">Interface</div>
<li className="nav-item">
<a
className="nav-link collapsed"
href="#"
data-toggle="collapse"
data-target="#collapseTwo"
aria-expanded="true"
aria-controls="collapseTwo"
>
<i className="fas fa-fw fa-cog"></i>
<span>Components</span>
</a>
<div
id="collapseTwo"
className="collapse"
aria-labelledby="headingTwo"
data-parent="#accordionSidebar"
>
<div className="bg-white py-2 collapse-inner rounded">
<h6 className="collapse-header">Custom Components:</h6>
<a className="collapse-item" href="buttons.html">
Buttons
</a>
<a className="collapse-item" href="cards.html">
Cards
</a>
</div>
</div>
</li>
<li className="nav-item">
<a
className="nav-link collapsed"
href="#"
data-toggle="collapse"
data-target="#collapseUtilities"
aria-expanded="true"
aria-controls="collapseUtilities"
>
<i className="fas fa-fw fa-wrench"></i>
<span>Utilities</span>
</a>
<div
id="collapseUtilities"
className="collapse"
aria-labelledby="headingUtilities"
data-parent="#accordionSidebar"
>
<div className="bg-white py-2 collapse-inner rounded">
<h6 className="collapse-header">Custom Utilities:</h6>
<a className="collapse-item" href="utilities-color.html">
Colors
</a>
<a className="collapse-item" href="utilities-border.html">
Borders
</a>
<a className="collapse-item" href="utilities-animation.html">
Animations
</a>
<a className="collapse-item" href="utilities-other.html">
Other
</a>
</div>
</div>
</li>
<hr className="sidebar-divider" />
<div className="sidebar-heading">Addons</div>
<li className="nav-item">
<a
className="nav-link collapsed"
href="#"
data-toggle="collapse"
data-target="#collapsePages"
aria-expanded="true"
aria-controls="collapsePages"
>
<i className="fas fa-fw fa-folder"></i>
<span>Pages</span>
</a>
<div
id="collapsePages"
className="collapse"
aria-labelledby="headingPages"
data-parent="#accordionSidebar"
>
<div className="bg-white py-2 collapse-inner rounded">
<h6 className="collapse-header">Login Screens:</h6>
<a className="collapse-item" href="login.html">
Login
</a>
<a className="collapse-item" href="register.html">
Register
</a>
<a className="collapse-item" href="forgot-password.html">
Forgot Password
</a>
<div className="collapse-divider"></div>
<h6 className="collapse-header">Other Pages:</h6>
<a className="collapse-item" href="404.html">
404 Page
</a>
<a className="collapse-item" href="blank.html">
Blank Page
</a>
</div>
</div>
</li>
<li className="nav-item">
<a className="nav-link" href="charts.html">
<i className="fas fa-fw fa-chart-area"></i>
<span>Charts</span>
</a>
</li>
<li className="nav-item">
<a className="nav-link" href="tables.html">
<i className="fas fa-fw fa-table"></i>
<span>Tables</span>
</a>
</li>
<hr className="sidebar-divider d-none d-md-block" />
<div className="text-center d-none d-md-inline">
<button className="rounded-circle border-0" id="sidebarToggle" />
</div>
</ul>
</div>
);
};
ProtectedLayout.jsx (layout rendered when logged in)
import { Outlet } from "react-router";
import { Navbar } from "../components/common/Navbar";
import { TopBar } from "../components/common/Topbar";
export const ProtectedLayout = () => {
return (
<>
<div>
<TopBar />
<Navbar />
</div>
<Outlet />
</>
);
};
App.js (routing)
import React from "react";
import { Route, Routes } from "react-router-dom";
import { LoginLayout } from "./layout/LoginLayout";
import { ProtectedLayout } from "./layout/ProtectedLayout";
import { ProtectRoutes } from "./hooks/protectedRoute";
import { Login } from "./pages/LoginPage";
import { Dashboard } from "./pages/DashboardPage";
import { Hi } from "./pages/HiPage";
import { About } from "./pages/AboutPage";
export default function App() {
return (
<Routes>
<Route element={<LoginLayout />}>
<Route path="/" element={<Login />} />
</Route>
<Route path="/auth" element={<ProtectRoutes />}>
<Route
path="/auth/dashboard"
element={
<>
<ProtectedLayout />
<Dashboard />
</>
}
/>
<Route
path="/auth/hi"
element={
<>
<ProtectedLayout />
<Hi />
</>
}
/>
<Route
path="/auth/about"
element={
<>
<ProtectedLayout />
<About />
</>
}
/>
</Route>
</Routes>
);
}
Also, if you have any suggestions on bettering the routing I would be incredibly grateful.
Please let me know if you need any other code.

How to change color of icon and text once clicked or hovering?

I'm new to coding and working on project right now. I currently have a side Navbar and I'm trying to get the icon and text to change color when I either hover over it, or once I click on that route, (for example, if I click on Home) it'll stay blue, until I click on another link, and keeps it blue while I'm hovering over other links.
This is my code for my side navBar :
const Navbar = ({ handleClick, isLoggedIn, email }) => (
<div className="wrapper">
<nav
className="navbar navbar-expand d-flex flex-column align-item-center-start"
id="sidebar"
>
<a href="/" className="navbar-brand text-light mt-2">
<div className="display-6 font-weight-bold">
<span>SPODify +</span>
</div>
</a>
<ul className="navbar-nav d-flex flex-column w-100 mt-4">
<li className=" h-25 nav-item border-bottom">
<a href="/" className="nav-link text-light pl-4">
<i className="bi bi-house-door "></i>
HOME
</a>
</li>
<li className="h-25 nav-item border-bottom">
<a href="#" className="nav-link text-light ">
<i className="bi bi-search"></i>
SEARCH
</a>
</li>
<li className="nav-item h-10 border-bottom">
<a href="/show" className="nav-link text-light ">
<i className="bi bi-rainbow"></i>
PODCASTS
</a>
</li>
<li className="nav-item h-25 border-bottom">
<a href="#" className="nav-link text-light pl-4">
<i className="bi bi-collection"></i>
YOUR LIBRARY
</a>
</li>
{isLoggedIn ? (
<>
<li className="nav-item h-25 border-bottom">
<a href="/login" className="nav-link text-light pl-4">
<i className="bi bi-person-circle"></i>
{email}
</a>
</li>
<li className="nav-item h-25 border-bottom">
<a
href="#"
onClick={handleClick}
className="nav-link text-light pl-4"
>
LOGOUT
</a>
</li>
</>
) : (
<li className="nav-item h-25 border-bottom">
<a href="/login" className="nav-link text-light pl-4">
LOGIN
</a>
</li>
)}
</ul>
</nav>
<div>
{isLoggedIn ? (
<div>
<Home email={email} />{" "}
</div>
) : (
<div>
<h1>WELCOME, SIGN UP</h1>
<Signup />
</div>
)}
</div>
</div>
);
I tried to achieve this by adding this to my CSS file:
nav a.nav-link:hover {
background-color: blue;
}
But this just makes the entire section blue :
Any tips on how I can change ONLY the icon and text when I hover over it and once I click on the link? Thanks in advance!
For reference, this is what I'm trying to achieve:
Currently clicked on Home link and hovering over Guests that's why it's both a different color
Your on the right way. To change the color of the text and icon you'll need to change background-color to color this css:
nav a.nav-link:hover {
color: blue;
}
Example:
a:hover{
color: blue;
}
<ul>
<li>
<a>My Test</a>
</li>
</ul>
For the active part (once you clicked) you need to add an extra class for that. (example: .active). Then you can style it the same way as when you are hovering it:
a:hover,
a.active{
color: blue;
}

How do I add a transition to my navbar menu in react when I click the toggle button

I have created an e-commerce base template in HTML and CSS / Bootstrap. I am trying to convert the template to React components for a NextJS site, but the toggle function was not initially working. I saw I can use React Hooks to toggle classes, which I have implemented using useState/isActive. The hamburger transition works but the transition for the actual menu does not.
Here is navbar.js
import Logo from '../images/logo-small-cropped.png'
import Image from 'next/image'
import React, { useState } from "react"
export default function Navbar({ }) {
const [isActive, setActive] = useState("false");
const handleToggle = () => {
setActive(!isActive);
};
return (
<nav className="navbar navbar-expand-md navbar-light border-top fixed-top border-bottom py-0" >
<div className="container-fluid text-center" >
<a className="navbar-brand" href="#">
<span className="mb-2">
<Image src={Logo} alt="Little Pink Boutique Logo" />
</span>
</a>
<button onClick={handleToggle} className="navbar-toggler navbar-toggler-button" type="button" aria-label="Toggle navigation">
<div id="hamburger" className={isActive ? "null" : "open"}>
<span></span>
<span></span>
<span></span>
</div>
</button>
<div className={isActive ? "collapse navbar-collapse" : "navbar-collapse"} >
<ul className="navbar-nav me-auto mb-2 mb-md-0">
<li className="nav-item">
<a className="nav-link active" aria-current="page" href="/home" > </a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Women</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Men</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Children</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Accessories</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">FAQs</a>
</li>
<li className="nav-item">
<a className="nav-link" href="#">Contact</a>
</li>
</ul>
<form className="d-flex">
<input className="form-control me-2 mt-3 mb-2" type="search" placeholder="Search" aria-label="Search"/>
<button className="btn btn-outline-success mt-3 mb-2" type="submit">Search</button>
</form>
</div>
</div>
</nav>
)
}
The .collapse class is just the standard Bootstrap class, the navbar-collapse class is as follows.
.navbar-collapse{
background-color: rgb(238, 236, 236);
width: 100vw;
}
I'm not sure how to get the transition to work, or if this is the best way to do it.
Any help appreciated as always.
Try using the transition css property in the navbar-collapse class.
Something like this :-
.navbar-collapse{
transition: width 2s;
background-color: rgb(238, 236, 236);
width: 100vw;
}

Is there a way to hide a div in Blazor?

I am using Blazor and I want to hide the sidebar when I press on the navbar-toggler-icon. The list items collaps but the problem is that the div is still there.
<div class="page">
<div class="sidebar">
<div class="nav-top-row pl-4 navbar navbar-dark">
<button class="navbar-toggler" #onclick="CheckCollapse">
<span class="navbar-toggler-icon"></span>
</button>
<a class="navbar-brand" href="">NavBar</a>
</div>
<div class="#NavMenuCssClass">
<ul class="nav flex-column">
<li class="nav-item px-0">
<NavLink class="nav-link" href="" Match="NavLinkMatch.All">
<span class="oi oi-home" aria-hidden="true"></span> Home
</NavLink>
</li>
<li class="nav-item px-0">
<NavLink class="nav-link" href="counter">
<span class="oi oi-plus" aria-hidden="true"></span> Counter
</NavLink>
</li>
<li class="nav-item px-0">
<NavLink class="nav-link" href="fetchdata">
<span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
</NavLink>
</li>
</ul>
</div>
</div>
<div class="main">
<div class="top-row px-4">
About
</div>
<div class="content px-4">
#Body
</div>
</div>
</div>
#code {
private bool collapseNavMenu = false;
public string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
private void CheckCollapse()
{
collapseNavMenu = !collapseNavMenu;
}
}
It's easier than you think.
#if(!collapseNavMenu)
{
<div class="sidebar">
... as before
</div>
}

Vue.js : How to make dynamic menu?

Could someone help me with creating menus dynamically from a database? Lets say all the data from the database is already supplied by me, but I want to show a dynamic menu if a user is logged in or not.
I created some Vue components
App.vue
<template>
<div id="app">
<navbar></navbar>
<div class="page-container">
<leftmenu></leftmenu>
<container></container>
</div>
</div>
</template>
<script>
import Menu from './components/Menu.vue'
import LeftMenu from './components/Leftmenu.vue'
import Container from './components/Container.vue'
export default {
components: {
'navbar': Menu,
'leftmenu': LeftMenu,
'container': Container,
}
}
</script>
The LeftMenu component is in charge of making the menu that will make use of the database data:
Leftmenu.vue
<template>
<div class="page-sidebar-wrapper">
<div class="page-sidebar navbar-collapse collapse">
<ul class="page-sidebar-menu page-header-fixed " data-keep-expanded="false" data-auto-scroll="true"
data-slide-speed="200" style="padding-top: 20px">
<li class="sidebar-toggler-wrapper hide">
<div class="sidebar-toggler">
<span></span>
</div>
</li>
<li class="nav-item start active open">
<a href="javascript:;" class="nav-link nav-toggle">
<i class="icon-home"></i>
<span class="title">Dashboard</span>
<span class="selected"></span>
<span class="arrow open"></span>
</a>
<ul class="sub-menu">
<router-link
to="/home"
tag="li">
<a class="nav-link">
<i class="icon-layers"></i>
<span class="title">Home</span>
<span class="badge badge-danger">5</span>
</a>
</router-link>
<router-link
to="/grafik"
tag="li">
<a class="nav-link">
<i class="icon-layers"></i>
<span class="title">Grafik</span>
<span class="badge badge-danger">5</span>
</a>
</router-link>
<router-link
to="/form"
tag="li">
<a class="nav-link">
<i class="icon-layers"></i>
<span class="title">Form</span>
<span class="badge badge-danger">5</span>
</a>
</router-link>
<router-link
to="/uploadfile"
tag="li">
<a class="nav-link">
<i class="icon-layers"></i>
<span class="title">Upload File</span>
<span class="badge badge-danger">5</span>
</a>
</router-link>
<router-link
to="/login"
tag="li">
<a class="nav-link">
<i class="icon-layers"></i>
<span class="title">Login</span>
<span class="badge badge-danger">5</span>
</a>
</router-link>
</ul>
</li>
<li class="nav-item ">
<a href="javascript:;" class="nav-link nav-toggle">
<i class="icon-settings"></i>
<span class="title">System</span>
<span class="arrow"></span>
</a>
<ul class="sub-menu">
<li class="nav-item ">
<a href="ui_metronic_grid.html" class="nav-link ">
<span class="title">Login</span>
</a>
</li>
<li class="nav-item ">
<a href="ui_metronic_grid.html" class="nav-link ">
<span class="title">Ganti Password</span>
</a>
</li>
<li class="nav-item ">
<a href="ui_metronic_grid.html" class="nav-link ">
<span class="title">Ganti Profil</span>
</a>
</li>
<li class="nav-item ">
<a href="ui_metronic_grid.html" class="nav-link ">
<span class="title">Logout</span>
</a>
</li>
</ul>
</li>
</ul>
</div>
</div>
</template>
<script>
import _ from 'lodash'
export default {
created() {
if(_.isEmpty(this.$auth.getAuthenticatedUser())) {
alert('empty')
} else {
alert('user authenticated')
}
}
}
</script>
this.$auth.getAuthenticatedUser() is already done but will return an empty object if my localStorage is empty. It will but filled if I am logged in.
I am using this bit of code for it:
this.$http.get('api/getmenu')
.then(response => {
this.data = response.body
})
In which component should I query the database to obtain the data to render a menu for the logged in user?
If I place a function to query the database inside my App.vue component, then the application will show an error.
What should I put in the Leftmenu component ?

Categories