How to display different styled Navbars on different pages in ReactJS? - reactjs

I have three different Navbars. Each of them is a different component.
<PublicNavbar /> ,which is for public pages such as LandingPage, DiscoverPage etc.
<AccessNavbar /> ,which is for SignInPage, SignUppage, VerificationPage etc.
<PrivateNavbar /> , which is for private pages such as NewCampaignPage etc.
How can I show them properly? If a user is logged in, I want to replace DiscoverPage's PublicNavbar with PrivateNavbar.
import React from "react";
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import "semantic-ui-css/semantic.min.css";
import "./App.css";
import PublicNavbar from "./components/Navbar/PublicNavbar";
import AccessNavbar from "./components/Navbar/AccessNavbar";
import PrivateNavbar from "./components/Navbar/PrivateNavbar";
import Footer from "./components/Footer";
import LandingPage from "./pages/LandingPage";
import SignIn from "./pages/SIgnInPage";
import DiscoverPage from "./pages/DiscoverPage";
import SignUp from "./pages/SignUpPage";
import Verification from "./pages/VerificationPage";
import Registration from "./pages/RegistrationPage";
import RegistrationComplete from "./pages/RegistrationCompletePage";
import NewCampaign from "./pages/NewCampaignPage";
function App() {
return (
<Router>
<div>
<div id="container">
<div id="main">
<Switch>
<Route path="/" exact component={LandingPage} />
<Route path="/discover" component={DiscoverPage} />
<Route path="/signIn" component={SignIn} />
<Route path="/signUp" component={SignUp} />
<Route path="/verification" component={Verification} />
<Route path="/registration" component={Registration} />
<Route
path="/registration-complete"
component={RegistrationComplete}
/>
<Route path="/new-campaign" component={NewCampaign} />
</Switch>
</div>
</div>
<Footer />
</div>
</Router>
);
}
export default App;
Sample Navbar code:
import React from "react";
const PublicNavbar = () => {
return (
<nav className="navbar navbar-expand-lg bg-white">
<div className="container-fluid navbar-container">
<a className="navbar-brand abs nav-bar-title" href="#">
AshoDaanKori
</a>
<button
className="navbar-toggler ms-auto custom-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#collapseNavbar"
>
<span className="navbar-toggler-icon"></span>
</button>
<div className="navbar-collapse collapse" id="collapseNavbar">
<ul className="navbar-nav ms-auto">
<li className="nav-item active">
<a
className="nav-link"
href=""
data-bs-target="#myModal"
data-bs-toggle="modal"
>
About
</a>
</li>
<li className="nav-item active">
<a
className="nav-link"
href=""
data-bs-target="#myModal"
data-bs-toggle="modal"
>
How it works
</a>
</li>
<li className="nav-item active">
<a
className="nav-link"
href=""
data-bs-target="#myModal"
data-bs-toggle="modal"
>
Discover
</a>
</li>
</ul>
<a
className="nav-link navbar-btn"
href=""
data-bs-target="#myModal"
data-bs-toggle="modal"
>
Start Campaign
</a>
</div>
</div>
</nav>
);
};
export default PublicNavbar;

Create a new Navbar component named something like NavBarController.
While calling the navbar controller component pass in the "Type" as prop. Type should be a state and should change depending on the user status.
<NavBarController type={1}></NavBarController>
Let NavBarController handle whichever navbar you want to display out of your three navbars
(where type will be 1,2 or 3).
Your NavBarController will return something like this:
return (props.type===1?<PublicNavbar/>
:props.type===2?<AccessNavbar/>
:props.type===3?<PrivateNavbar/>)

Solved it by conditional rendering. Without creating multiple Navbar components, I created one and changed the inner elements based on condition.
const Navbar = ({ isAuthenticated }) => {
return (
<nav
className={`autohide navbar navbar-expand-lg bg-white ${
isAuthenticated ? "private-navbar" : ""
}`}
>
<div className="container-fluid navbar-container">
<NavHashLink className="navbar-brand abs nav-bar-title" to="/">
AshoDaanKori
</NavHashLink>
<button
className="navbar-toggler ms-auto custom-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#main_nav"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
{isAuthenticated ? (
<div className="collapse navbar-collapse" id="main_nav">
<ul className="navbar-nav ms-auto">
<li className="nav-item active">
<NavHashLink to="/my-fundraisers" className="nav-link">
My fundraisers
</NavHashLink>
</li>
</ul>
<Link to="/start-campaign" className="nav-link navbar-btn">
Start a new campaign
</Link>
{/* User profile */}
<div className="btn-group nav-item">
<button
type="button"
className="btn "
data-bs-toggle="dropdown"
data-bs-display="static"
aria-expanded="false"
style={{ padding: "0" }}
>
<i aria-hidden="true" className="user circle huge icon"></i>
</button>
<ul className="dropdown-menu dropdown-menu-end">
<li>
<h3
style={{
textAlign: "center",
fontSize: 18,
fontWeight: 600,
color: "#6E6E6E",
}}
>
{userInfo.fullName || "User"}
</h3>
</li>
<li>
<hr className="dropdown-divider" />{" "}
</li>
<li>
<Link className="dropdown-item" to="/account">
Account Settings
</Link>
</li>
<li>
<Link
className="dropdown-item"
to="#"
>
Sign Out
</Link>
</li>
</ul>
</div>
</div> //If authenticated, rendered PrivateNavbar elements
) : (
<div className="collapse navbar-collapse" id="main_nav">
<ul className="navbar-nav ms-auto">
<li className="nav-item active">
<NavHashLink
smooth
to="/#our-story-section"
className="nav-link"
>
About
</NavHashLink>
</li>
<li className="nav-item active">
<NavHashLink to="/how-it-works" className="nav-link">
How it works
</NavHashLink>
</li>
<li className="nav-item active">
<NavHashLink to="/discover" className="nav-link">
Discover
</NavHashLink>
</li>
</ul>
<NavHashLink to="/sign-in" className="nav-link navbar-btn">
START CAMPAIGN
</NavHashLink>
</div> //If not authenticated, rendered PublicNavbar elements
)}
</div>
</nav>
);
};
export default Navbar;

Related

how to make a NavLink activeClassName change background color when clicked

i am trying to make a nav bar when a navlink is clicked i want the activelink to change background-color
i have used NavLink but it is not woeking for some reasome pls help
export class side extends Component {
render() {
return (
<div className="l-navbar " id="nav-bar">
<nav className="nav">
<NavLink
activeClassName="active3"
className="porpssidebar"
exact={true}
to="/"
>
<div>
<a href="#" className="nav_logo">
<img className="slogo" src={forur} />
<i className="fas fa-angry"></i>{" "}
</a>
</div>
</NavLink>
<NavLink activeClassName="active3" exact={true} to="/orders">
<div>
{" "}
<a href="#" className="nav_logo">
<Orders />
<i className="fas fa-angry"></i>{" "}
</a>
</div>
</NavLink>
<NavLink to="/customers" activeClassName="active3">
<div>
{" "}
<a href="#" className="nav_logo">
<Package />
<i className="fas fa-angry"></i>{" "}
</a>
</div>
</NavLink>
</div>
);
}
}
export default side;
in app.css i have a class called active3 for changing color
.active3 {
background: black;
}

Page goes blank when I try to use a certain component

I pulled code from git repo and added two new file components Men.js and Card.js to it. When I try to route to components Men.js or Card.js the page goes blank but all other existing components in the folder gets rendered. No error is displayed.
Even without routing the Men and Card does not get displayed when I use them in App.js
Navbar.js
import React from "react";
import './style.css'
import {BrowserRouter,Route,Routes, Link} from 'react-router-dom';
import Home from "./Home";
import Usersignin from "./Usersignin";
import Usersignup from "./Usersignup";
import Nav from "./Nav";
import Card from "./Card";
import Footer from "./Footer";
import Men from "./Men";
export default function Navbar() {
return (
<>
<BrowserRouter>
<Nav/>
<Routes>
<Route exact path='/' element={<Home/>}/>
<Route exact path='/signin' element={<Usersignin/>}/>
<Route exact path='/signup' element={<Usersignup/>}/>
<Route exact path='/women' element={<Card/>}/>
<Route exact path='/men' element={<Men/>}/>
</Routes>
</BrowserRouter>
</>
);
}
Nav.js
import React from 'react'
import {Link} from 'react-router-dom'
export default function Nav() {
return (
<div class="container-fluid" id="nav-container">
<nav className="container-fluid navbar navbar-expand-lg Navbar shadow px-2">
<div className="container-fluid">
<Link className="navbar-brand" to="/">
E-commerce
</Link>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent"
aria-controls="navbarSupportedContent"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarSupportedContent">
<ul className="navbar-nav me-auto mb-2 mb-lg-0">
<li className="nav-item">
<Link className="nav-link" aria-current="page" to="/">
Home
</Link>
</li>
<li className="nav-item dropdown">
<a
className="nav-link dropdown-toggle"
to="#"
id="navbarDropdown"
role="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
All Products
</a>
<ul className="dropdown-menu" aria-labelledby="navbarDropdown">
<li>
{/* <a className="dropdown-item" to="#">
1st Product
</a> */}
<Link className="dropdown-item" aria-current="page" to="/men">Men</Link>
</li>
<li>
{/* <a className="dropdown-item" to="#">
2nd Product
</a> */}
<Link className="dropdown-item" aria-current="page" to="/women">Women</Link>
</li>
{/* <li>
<hr className="dropdown-divider" />
</li> */}
<li>
{/* <a className="dropdown-item" to="#">
3rd Product
</a> */}
<Link className="dropdown-item" aria-current="page" to="/">Kids</Link>
</li>
</ul>
</li>
<li className="nav-item">
<Link className="nav-link" to="#">
Order Form
</Link>
</li>
<li className="nav-item">
<a className="nav-link">Gallery</a>
</li>
<li className="nav-item">
<Link className="nav-link" to='/signin'>Sign In</Link>
</li>
<li className="nav-item">
<Link className="nav-link" to='/signup'>Sign Up</Link>
</li>
</ul>
</div>
</div>
</nav>
</div>
)
}
Men.js
import React from 'react'
import Card from './Card'
export default function Men() {
return (
<>
<Card/>
<Card/>
<Card/>
</>
)
}
Card.js
import React from 'react'
export default function Card() {
return (
<div class="card" style="width: 18rem;">
<img src="..." class="card-img-top" alt="..."/>
<div class="card-body">
<h5 class="card-title">Card title</h5>
<p class="card-text">Some quick example text to build on the card title and make up the bulk of the card's content.</p>
Go somewhere
</div>
</div>
)
}
All other components like Usersignin,Usersignup,Home all render, they are from the existing git repo that I pulled while Men and Card components I have added. I m not getting why this happens please help me.
I've cloned Your repo and add missing components (Men.js and Card.js) You have problem with Card.js component.
You need to change:
class to className
style="width: 18rem;" to style={{ width: "18rem" }}
(https://reactjs.org/docs/dom-elements.html#style)
Like that and it works like a charm ! ;-) But You have still a lot warnings and a lot to do ;-)
import React from "react";
export default function Card() {
return (
<div className="card" style={{ width: "18rem" }}>
<img src="..." className="card-img-top" alt="..." />
<div className="card-body">
<h5 className="card-title">Card title</h5>
<p className="card-text">
Some quick example text to build on the card title and make up the
bulk of the card's content.
</p>
<a href="#" className="btn btn-primary">
Go somewhere
</a>
</div>
</div>
);
}
http://localhost:3000/men Output :
http://localhost:3000/women Output:

Redirecting with clicked link, React, RRD6

sorry about title name, i cant name my problem, but basically: My navbar dropdown menu looks like this:
Home Dropdown 🠗 Contact
Sign In
Register
Problem is, when somebody clicks on SignIn and then clicks on Register (and conversely), the url will look like this: http://localhost:3000/signupform/signin so browser will tell that this page does not exist.
But it should look like that: http://localhost:3000/signupform
Thanks everybody so much.
Navbar code (without imports):
const Navbar = () => {
const [isMenu, setisMenu] = useState(false);
const [isResponsiveclose, setResponsiveclose] = useState(false);
const toggleClass = () => {
setisMenu(isMenu === false ? true : false);
setResponsiveclose(isResponsiveclose === false ? true : false);
};
let boxClass = ["main-menu menu-right menuq1"];
if(isMenu) {
boxClass.push('menuq2');
}else{
boxClass.push('');
}
const [isMenuSubMenu, setMenuSubMenu] = useState(false);
const toggleSubmenu = () => {
setMenuSubMenu(isMenuSubMenu === false ? true : false);
};
let boxClassSubMenu = ["sub__menus"];
if(isMenuSubMenu) {
boxClassSubMenu.push('sub__menus__Active');
}else {
boxClassSubMenu.push('');
}
return (
<header>
<nav>
<div className="container">
<div className="row">
<div className="header__middle__logo">
<Link to exact activeClassName='is-active' to="/">
<FontAwesomeIcon icon={faMagnifyingGlass} size="4x" color="white" alt="logo" />
</Link>
</div>
<div className="header__middle__menus">
<nav className="main-nav " >
{/* Responsive Menu Button */}
{isResponsiveclose === true ? <>
<span className="menubar__button" style={{ display: 'none' }} onClick={toggleClass} > <FiXCircle /> </span>
</> : <>
<span className="menubar__button" style={{ display: 'none' }} onClick={toggleClass} > <FiAlignRight /> </span>
</>}
<ul className={boxClass.join(' ')}>
<li className="menu-item" >
<Link to exact activeClassName='is-active' onClick={toggleClass} to={`/`}> Home </Link>
</li>
<li className="menu-item " ><Link onClick={toggleClass} activeClassName='is-active' to={`/contact`}> </Link> </li>
<li onClick={toggleSubmenu} className="menu-item sub__menus__arrows" > <Link to="#"> Sign <FiChevronDown /> </Link>
<ul className={boxClassSubMenu.join(' ')} >
<li> <Link onClick={toggleClass} activeClassName='is-active' to={`signin`}> Přihlásit se </Link> </li>
<li><Link onClick={toggleClass} activeClassName='is-active' to={`signupform`}> Registrovat se </Link> </li>
</ul>
</li>
<li className="menu-item " ><Link onClick={toggleClass} activeClassName='is-active' to={`/Contact`}> Contact </Link> </li>
</ul>
</nav>
</div>
</div>
</div>
</nav>
</header>

reactjs: how to show nav items based on backend permissions

I have this navbar where the user can navigate through the site and logged in users can make posts on the main page or news posts on the news page. However, i have 3 levels of permissions made in the backend where the visitors are allowed to navigate the website, then authenticated users can make normal posts or news posts but the last one is admin only permission to make a program post. the question is how can i show the third button (which is for program post) not show for authenticated users and only pop up when an admin logs in
these buttons can be found in the code bellow under authLinks
import { Link, NavLink } from 'react-router-dom';
import { connect } from 'react-redux';
import { logout } from '../actions/auth';
import Alert from './Alert';
import PropTypes from 'prop-types';
import {Navbar, NavDropdown} from "react-bootstrap";
import Logo from '../assets/images/logo.png';
const navbar = ({ auth:{isAuthenticated, loading}, logout}) => {
const authLinks = (
<Fragment>
<NavLink className='btn btn-primary btn-sm m-2' to='/create-post'>Nytt innlegg</NavLink>
<NavLink className='btn btn-primary btn-sm m-2' to='/create-nyhet'>Nytt nyhetsinnlegg</NavLink>
<NavLink className='btn btn-primary btn-sm m-2' to='/create-program'>Nytt arrangement</NavLink>
<a className='btn btn-primary btn-sm m-2' onClick={logout} href='#!'>Logg ut</a>
</Fragment>
);
const guestLinks = (
<NavLink className='btn btn-primary btn-sm m-2' to='/login'>Logg inn</NavLink>
);
return(
<Fragment>
<Navbar bg="dark" variant="dark" expand="md" sticky="top">
<div className="container-fluid">
<Navbar.Brand href='/'><img className="img-responsive" src={Logo} width="220" height="55" alt="Sammfunnet Logo" /></Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<ul className="navbar-nav p-2">
<li className="nav-item active">
<NavLink className="nav-link" exact to='/'>Hjem</NavLink>
</li>
<li className="nav-item">
<NavLink className="nav-link" exact to='/nyhet'>Nyhet</NavLink>
</li>
<li className="nav-item">
<NavLink className="nav-link" exact to='/program'>Program</NavLink>
</li>
<NavDropdown title="Kontakt Oss" id="basic-nav-dropdown">
<NavDropdown.Item href="/bli-frivillig">Bli Frivillig</NavDropdown.Item>
<NavDropdown.Item href="/presse">Presse</NavDropdown.Item>
<NavDropdown.Item href="#action/3.3">Samarbeid</NavDropdown.Item>
</NavDropdown>
<li className="nav-item">
<NavLink className="nav-link" exact to='/omoss'>Om oss</NavLink>
</li>
</ul>
</Navbar.Collapse>
<span className="nav_link">
{ !loading && (<Fragment>{ isAuthenticated ? authLinks : guestLinks }</Fragment>) }
</span>
</div>
</Navbar>
<Alert />
</Fragment>
);
};
navbar.propTypes = {
logout: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired
}
const mapStateToProps = state => ({
auth: state.auth
});
export default connect(mapStateToProps, { logout })(navbar);
Do this then should work
const authLinks = (
<Fragment>
<NavLink className='btn btn-primary btn-sm m-2' to='/create-post'>Nytt innlegg</NavLink>
<NavLink className='btn btn-primary btn-sm m-2' to='/create-nyhet'>Nytt nyhetsinnlegg</NavLink>
{ isAuthenticated && (<NavLink className='btn btn-primary btn-sm m-2' to='/create-program'>Nytt arrangement</NavLink> ) }
<a className='btn btn-primary btn-sm m-2' onClick={logout} href='#!'>Logg ut</a>
</Fragment>
);

React Jest click nav item in unit test

I have a bootstrap navigation menu and I am trying to simulate a click of a nav item on a nav dropdown in React with Jest. I have the following dropdown:
Navbar.js
export default props => {
const { user, email, group } = props;
return (
<Nav className="navbar navbar-expand navbar-light bg-white topbar mb-4 static-top shadow">
<button
type="button"
id="sidebarToggleTop"
className="btn btn-link d-md-none rounded-circle mr-3"
>
<FontAwesomeIcon icon={faBars} />
</button>
<ul className="navbar-nav ml-auto">
<div className="topbar-divider d-none d-sm-block" />
<NavDropdown
data-testid="profile-dropdown"
className="no-arrow"
title={
<>
<span className="mr-2 d-none d-lg-inline text-gray-600 small">
{user}
</span>
{email && (
<Gravatar
email={email}
className="img-profile rounded-circle"
/>
)}
</>
}
id="userDropdown"
>
<div className="dropdown-item">Profile: {group}</div>
<Link className="dropdown-item" to="/refresh">
Refresh
</Link>
<NavDropdown.Divider />
<NavDropdown.Item data-testid="sign-out-button" eventKey="logout" onSelect={() => Auth.signOut()}>
SignOut
</NavDropdown.Item>
</NavDropdown>
</ul>
</Nav>
);
};
Can anyone help? The item is not present in the DOM on render so I cannot use data-testid.

Resources