I changed my NavBarDesktop to add props in super like below. My HomePage shows but if I click on About Us or any other page, I get a blank page. I also added my HomePage Code below as well. I am not sure why it does this. If I take const MyView our the pages work but there is no categories in NavDropdown.
NavMenuDesktop
class NavMenuDesktop extends React.Component{
constructor(props){
super(props);
}
render(){
const CatList = this.props.data;
const MyView = CatList.map((CatList,i)=>{
return <div key={i.toString()}>
<NavDropdown.Item href="">{CatList.category_name}</NavDropdown.Item>
</div>
});
return(
<Fragment>
<Navbar bg="light" expand="lg" sticky="top">
<Container>
<Navbar.Brand href="/"><img src={Logo} className="nav-logo" /></Navbar.Brand>
<Navbar.Toggle aria-controls="responsive-navbar-nav" className="nav-toggler" ><i className="fa fa-bars"></i></Navbar.Toggle>
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
<Nav.Link href="/">Home</Nav.Link>
<Nav.Link href="/about">About Us</Nav.Link>
<NavDropdown title="Shop" id="basic-nav-dropdown" renderMenuOnMount={true}>
{MyView}
</NavDropdown>
<Nav.Link href="/contact">Contact</Nav.Link>
<NavDropdown title="My Account" id="collasible-nav-dropdown" renderMenuOnMount={true}>
<NavDropdown.Item href="/login"><i className="fa fa-sign-in-alt p-2 colorred"></i>Login</NavDropdown.Item>
<NavDropdown.Item href="#action/3.2"><i className="fa fa-user-plus p-2 colorred"></i>Register</NavDropdown.Item>
</NavDropdown>
<ul className="inline justify-content-right">
<li><Nav.Link href="/favorites"><i className="fa fa-heart fa-md text-secondary"></i>
<sup><span className="badge text-white bgred fa-md">5</span></sup>
</Nav.Link></li>
<li><Nav.Link href="/cart"><i className="fa fa-shopping-cart fa-md text-secondary"></i>
<sup><span className="badge text-white bgred fa-md">5</span></sup>
</Nav.Link>
</li>
</ul>
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</Fragment>
)
}
}
export default NavMenuDesktop;
HomePage
import React, { Component, Fragment } from 'react';
import { Container } from 'react-bootstrap';
import AppURL from '../api/AppURL';
import AppRoute from '../route/AppRoute';
import FeaturedProducts from '../components/home/FeaturedProducts';
import Categories from '../components/home/Categories';
import Collection from '../components/home/Collection';
import NewArrival from '../components/home/NewArrival';
import HomeTop from '../components/home/HomeTop';
import NavMenuDesktop from '../components/common/NavMenuDesktop';
import FooterDesktop from '../components/common/FooterDesktop'
import axios from 'axios';
class HomePage extends Component {
constructor(){
super();
this.state ={
MenuData:[]
}
}
componentDidMount(){
window.scroll(0,0);
this.GetVisitorDetails();
axios.get(AppURL.CategoryInfo).then(response =>{
this.setState({MenuData:response.data});
}).catch(error=>{
});
}
GetVisitorDetails = ()=>{
axios.get(AppURL.VisitorDetails).then().catch()
}
render() {
return (
<Fragment>
<NavMenuDesktop data={this.state.MenuData}/>
<HomeTop />
<Container fluid={"true"}>
<Categories />
<NewArrival />
<FeaturedProducts />
<Collection />
<FooterDesktop/>
</Container>
</Fragment>
)
}
}
export default HomePage;
in constructor use super(props) then write the myView const in componentDidMount() function like this:
componentDidMount(){
const CatList = this.props.data;
const MyView = CatList.map((CatList,i)=>{
return <div key={i.toString()}>
<NavDropdown.Item href="">{CatList.category_name}</NavDropdown.Item>
</div>
});
window.scroll(0,0);
this.GetVisitorDetails();
axios.get(AppURL.CategoryInfo).then(response =>{
this.setState({MenuData:response.data});
}).catch(error=>{
});
}
Related
I want to update the text color of the content inside the bar, but for some reason it doesn't work.
What I've tried so far: Link a css stylesheet (it doesn't work for some reason)
inline style (it only works for the company name and the cart, not for the user's name)
Here is the code to my header:
import React from 'react'
import { Route } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'
import { LinkContainer } from 'react-router-bootstrap'
import { Navbar, Nav, Container, NavDropdown } from 'react-bootstrap'
import SearchBox from './SearchBox'
import { logout } from '../actions/userActions'
import '../index.css' //changes in index.css do not update in header.js
const Header = () => {
const dispatch = useDispatch()
const userLogin = useSelector((state) => state.userLogin)
const { userInfo } = userLogin
const logoutHandler = () => {
dispatch(logout())
}
return (
<header>
<Navbar style={{ backgroundColor: '#0a4275' }} variant="light" expand='lg' collapseOnSelect >
<Container >
<LinkContainer to='/'>
<Navbar.Brand><span style={{ color: 'white' }}> CFM Système</span></Navbar.Brand>
</LinkContainer>
<Navbar.Toggle aria-controls='basic-navbar-nav' />
<Navbar.Collapse id='basic-navbar-nav'>
<Route render={({ history }) => <SearchBox history={history} />} />
<Nav className='ml-auto'>
<LinkContainer to='/cart'>
<Nav.Link>
<span style={{ color: 'white' }}> <i className='fas fa-shopping-cart'></i> Panier</span>
</Nav.Link>
</LinkContainer>
{userInfo ? (
<NavDropdown title={userInfo.name} id='username'>
<LinkContainer to='/profile'>
<NavDropdown.Item>Profil</NavDropdown.Item>
</LinkContainer>
<NavDropdown.Item onClick={logoutHandler}>
Se déconnecter
</NavDropdown.Item>
</NavDropdown>
) : (
<LinkContainer to='/login'>
<Nav.Link>
<i className='fas fa-user'></i> Se connecter
</Nav.Link>
</LinkContainer>
)}
{userInfo && userInfo.isAdmin && (
<NavDropdown title='Admin' id='adminmenu'>
<LinkContainer to='/admin/userlist'>
<NavDropdown.Item>Utilisateurs</NavDropdown.Item>
</LinkContainer>
<LinkContainer to='/admin/productlist'>
<NavDropdown.Item>Produits</NavDropdown.Item>
</LinkContainer>
<LinkContainer to='/admin/orderlist'>
<NavDropdown.Item>Commandes</NavDropdown.Item>
</LinkContainer>
</NavDropdown>
)}
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
</header>
)
}
export default Header
I'm clearly missing something, but I'm out of solutions?
I'm trying a double nested for loop but it's not quite unraveling how I predict, advice? am i not allowed to call a double for loop in function? Essentially it suppose to create a navbar from an array of objects i.e [{name:['Jonathan,'bob']},{dob:['may 21','june 22']}]
import React,{Component} from "react";
import Container from 'react-bootstrap/Container';
import Nav from 'react-bootstrap/Nav';
import Navbar from 'react-bootstrap/Navbar';
import NavDropdown from 'react-bootstrap/NavDropdown';
export function navBar(content){
return(
<Navbar bg="light" expand="lg">
<Container>
<Navbar.Brand href="#home">React-Bootstrap</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="me-auto">
{content.map((cont) => {
<NavDropdown title="Dropdown" id={Object.keys(cont)[0]}>
{
Object.values(cont).map((key)=>{<a href={"http://localhost:3000/"+key}>{key}</a>})
}
</NavDropdown>
})}
</Nav>
</Navbar.Collapse>
</Container>
</Navbar>
);
}
You are not returning from your map functions:
<Nav className='me-auto'>
{content.map((cont) => {
// from here
<NavDropdown title='Dropdown' id={Object.keys(cont)[0]}>
{Object.values(cont).map((key) => {
// and from here
<a href={'http://localhost:3000/' + key}>{key}</a>;
})}
</NavDropdown>;
})}
</Nav>
Solution:
<Nav className='me-auto'>
{content.map((cont) => {
return (<NavDropdown title='Dropdown' id={Object.keys(cont)[0]}>
{Object.values(cont).map((key) => {
return <a href={'http://localhost:3000/' + key}>{key}</a>;
})}
</NavDropdown>);
})}
</Nav>;
Since you are using arrow functions, you can omit the curly brackets and the return:
<Nav className='me-auto'>
{content.map((cont) => (
<NavDropdown title='Dropdown' id={Object.keys(cont)[0]}>
{Object.values(cont).map((key) => (
<a href={'http://localhost:3000/' + key}>{key}</a>
))}
</NavDropdown>
))}
</Nav>;
Also, the content parameter of your navBar is not an array but the props object, so you shouldn't be able to call map on it.
If you use navBar like: <navBar content={...}/>, you have to update its code like:
export function navBar({ content }){
// ...
}
could somone help i'm stuck in such problem with next.js here is my code
this is the error i get in the console
Error: Export encountered errors on following paths:
/admin
/user
in pages in folder named admin/index.js
import Layout from "../../components/Layout";
import Admin from "../../components/auth/Admin";
import Link from "next/link";
const AdminIndex = () => {
return (
<Layout>
<Admin>
<div className="container-fluid">
<div className="row">
<div className="col-md-12 pt-5 pb-5">
<h2>Admin Dashboard</h2>
</div>
<div className="col-md-4">
<ul class="list-group">
<li className="list-group-item">
<Link href="/admin/crud/project">
<a>Create Project</a>
</Link>
</li>
</ul>
</div>
<div className="col-md-8">right</div>
</div>
</div>
</Admin>
</Layout>
);
};
export default AdminIndex;
in folder pages/user/index.js
Error: Export encountered errors on following paths:
/admin
/user
import Layout from "../../components/Layout";
import Private from "../../components/auth/Private";
import Link from "next/link";
const UserIndex = () => {
return (
<Layout>
<Private>
<div className="container-fluid">
<h2>User Dashboard</h2>
</div>
</Private>
</Layout>
);
};
export default UserIndex;
and finally this is my header
import React, { useState } from "react";
import Link from "next/link";
import Router from "next/router";
import nProgress from "nprogress";
import { APP_NAME } from "../config";
import { signout, isAuth } from "../actions/auth";
import {
Collapse,
Navbar,
NavbarToggler,
Nav,
NavItem,
NavLink,
} from "reactstrap";
Router.onRouteChangeStart = (url) => nProgress.start();
Router.onRouteChangeComplete = (url) => nProgress.done();
Router.onRouteChangeError = (url) => nProgress.done();
//next.js giving us the option to use such option
const Header = () => {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => {
setIsOpen(!isOpen);
};
return (
<div>
<Navbar color="light" light expand="md">
<Link href="/">
<NavLink className="font-weight-bold">{APP_NAME}</NavLink>
</Link>
<NavbarToggler onClick={toggle} />
<Collapse isOpen={isOpen} navbar>
<Nav className="ml-auto" navbar>
{!isAuth() && (
<React.Fragment>
<NavItem>
<Link href="/signin">
<NavLink>Signin</NavLink>
</Link>
</NavItem>
<NavItem>
<Link href="/signup">
<NavLink>Signup</NavLink>
</Link>
</NavItem>
</React.Fragment>
)}
{isAuth() && isAuth().role === 0 && (
<NavItem>
<Link href="/user">
<NavLink style={{ cursor: "pointer" }}>
{`${isAuth().name}'s Dashboard`}
</NavLink>
</Link>
</NavItem>
)}
{isAuth() && isAuth().role === 1 && (
<NavItem>
<Link href="/admin">
<NavLink style={{ cursor: "pointer" }}>{`${
isAuth().name
}'s Dashboard`}</NavLink>
</Link>
</NavItem>
)}
{isAuth() && (
<NavItem>
<NavLink
style={{ cursor: "pointer" }}
onClick={() => signout(() => Router.replace(`/signin`))}
>
Signout
</NavLink>
</NavItem>
)}
</Nav>
</Collapse>
</Navbar>
</div>
);
};
export default Header;
I currently am storing user login in local storage and am rendering the appropriate nav bar depending. However, The page does not re-render upon sign-in or sign-out. I need to manually refresh the page to make it work. How can I use state in this scenario across several components?
import React, { useState } from "react";
import { Link } from "react-router-dom";
import { Navbar, Nav, Button } from "react-bootstrap";
import SignInModal from "././SignIn/SignInModal";
const NavBar = () => {
return localStorage.getItem("auth-token") ? <SignedIn /> : <SignedOut />;
};
const SignedIn = () => {
return (
<Navbar className="justify-content-around main-navbar">
<Nav.Item>
<Link className="link" to="/">
Signed Out
</Link>
</Nav.Item>
<Nav.Item>
<Link className="link" to="/mainsignedin">
Sign In
</Link>
</Nav.Item>
<Nav.Item>
<Link className="link" to="/searchpage">
Our Dogs
</Link>
</Nav.Item>
<Nav.Item>
<Link className="link" to="/mypets">
My Pets
</Link>
</Nav.Item>
<Nav.Item>
<Button type="submit" onClick={localStorage.clear()}>
Sign Out
</Button>
</Nav.Item>
</Navbar>
);
};
const SignedOut = () => {
return (
<Navbar>
<Nav.Item>
<SignInModal />
</Nav.Item>
</Navbar>
);
};
export default NavBar;
Here is code.
import SignInModal from "././SignIn/SignInModal";
import {useEffect, useState} from 'react';
const NavBar = () => {
const [isLogedIn,setIsloggedIn] =useState(false);
useEffect(()=>{
const auth_token = localStorage.getItem("auth-token") ;
setIsloggedIn(auth_token ? true:false);
},[])
const handleSignOut=()=>{
localStorage.clear()
setIsloggedIn(false);
}
return isLogedIn ? <SignedIn onSignOut={handleSignOut} /> : <SignedOut />;
};
const SignedIn = ({onSignOut}) => {
return (
<Navbar className="justify-content-around main-navbar">
<Nav.Item>
<Link className="link" to="/">
Signed Out
</Link>
</Nav.Item>
<Nav.Item>
<Link className="link" to="/mainsignedin">
Sign In
</Link>
</Nav.Item>
<Nav.Item>
<Link className="link" to="/searchpage">
Our Dogs
</Link>
</Nav.Item>
<Nav.Item>
<Link className="link" to="/mypets">
My Pets
</Link>
</Nav.Item>
<Nav.Item>
<Button type="submit" onClick={onSignOut}>
Sign Out
</Button>
</Nav.Item>
</Navbar>
);
};
const SignedOut = () => {
return (
<Navbar>
<Nav.Item>
<SignInModal />
</Nav.Item>
</Navbar>
);
};
export default NavBar;
You can use the useState hook to keep track of state in a React functional component.
You can use a Context to provide state to its children. Then, you can use the useContext hook within those children to access the state.
import React, { createContext, useContext } from 'react'
const MyContext = createContext({})
const MyContextProviderComponent = MyContext.Provider
const MyInnerComponent = () => {
const myValue = useContext(MyContext)
return <p>{myValue}</p>
}
const MyOuterComponent =() =>{
const [myValue, setMyValue] = useState('Hello world!')
return (
<MyContextProviderComponent value={myValue}>
<MyInnerComponent></MyInnerComponent>
</MyContextProviderComponent>
)
}
I'm newbie to programming and trying to build React App with REST API. Currently I retrieve and pass data from parent to child components by having two fetchData function in parent component since they have different API parameter. However, I'm doubt that this should be the right way as I still have more child components to build. It also has problem showing the data when refreshing a component page, I should navigate on routes before it shows. Please advise or link me a sample method on how should I handle my case.
Parent:
import React, {Component} from 'react';
import {BrowserRouter as Router, Route, Link} from 'react-router-dom';
import 'bootstrap/dist/css/bootstrap.min.css';
import {NavDropdown, Nav, Navbar} from 'react-bootstrap';
import axios from 'axios';
import * as constants from './components/constants/Constants'
import Home from './components/dashboard/home';
import AddCategories from './components/category/AddCategories';
import ViewCategories from './components/category/ViewCategories';
import AddAssets from './components/assets/AddAssets';
import ViewAssets from './components/assets/ViewAssets';
import './App.css';
class App extends Component{
constructor(props){
super(props);
this.state = {
assetItems:[],
categoryItems:[],
items : [],
currentPage: 1,
totalPages: 1,
totalItems: 1,
}
}
getAssetAssetItems=()=>{
this.setState({
currentPage: 1,
});
axios.get(constants.apiURL + 'Assets?&ShowAll=false')
.then(
(result)=>{
this.setState({assetItems: result.data.list, totalPages: result.data.totalPage, totalItems: result.data.total})
})
.catch(error =>console.log(error));
}
getCategoryItems=()=>{
axios.get(constants.apiURL + 'Categories?&ShowAll=false')
.then(
(result)=>{
this.setState({categoryItems: result.data.list, totalPages: result.data.totalPage, totalItems: result.data.total})
console.log(this.state.totalPages)
console.log(this.state.currentPage)
})
.catch(error =>console.log(error));
}
componentDidMount=()=>{
this.getAssetAssetItems();
this.getCategoryItems();
}
render(){
return(
<Router>
<div>
<Navbar bg="light" expand="lg">
<Navbar.Brand as={Link} to='/'>Asset Management</Navbar.Brand>
<Navbar.Toggle aria-controls="basic-navbar-nav" />
<Navbar.Collapse id="basic-navbar-nav">
<Nav className="mr-auto">
<Nav.Link as={Link} to='/Home'>Home</Nav.Link>
<Nav.Link as={Link} to='/Assets'>Assets</Nav.Link>
<NavDropdown title="Manage" id="basic-nav-dropdown">
<NavDropdown.Item as={Link} to='/manage/category'>Categories</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item as={Link} to='/manage/manufacturers'>Manufacturers</NavDropdown.Item>
<NavDropdown.Item href="#action/3.3">Models</NavDropdown.Item>
<NavDropdown.Item href="#action/3.4">Processors</NavDropdown.Item>
<NavDropdown.Item href="#action/3.5">Suppliers</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item>Sizes</NavDropdown.Item>
<NavDropdown.Item href="#action/3.6"> Hard Disk</NavDropdown.Item>
<NavDropdown.Item href="#action/3.7"> Memory</NavDropdown.Item>
<NavDropdown.Item href="#action/3.8"> Video Card</NavDropdown.Item>
</NavDropdown>
</Nav>
<Nav>
<Nav.Link href="users">Users</Nav.Link>
</Nav>
</Navbar.Collapse>
</Navbar>
<Route path='/Home' exact component={Home}/>
<Route path='/Assets'>
<AddAssets/>
<ViewAssets assetItems={this.state.assetItems}/>
</Route>
<Route path='/manage/category'>
<AddCategories/>
<ViewCategories categoryItems={this.state.categoryItems} totalPages={this.state.totalPages}/>
</Route>
</div>
</Router>
)
}
}
export default App;
Child 1:
import React, {Component} from 'react';
import {Button, Table} from 'react-bootstrap';
import axios from 'axios';
class ViewAssets extends Component{
constructor(props){
super(props);
this.state = {
assetItems : this.props.assetItems,
assetKeys : [],
currentPage: 1,
totalPage: 1,
totalItems: 1,
}
}
generateColumnHeader(){
return(
<tr >
<th>ID</th>
<th>Serial No.</th>
<th>Asset Tag</th>
<th>Host Name</th>
<th>Assigned To</th>
<th>Status Type</th>
<th>Manufacturer Name</th>
<th>Category Name</th>
<th>Purchase Date</th>
<th>Warranty</th>
<th>Actions</th>
</tr>
);
}
generateRowsData=()=>{
return(
this.state.assetItems.map(assets=>{
return(
<tr key={assets.id}>
<td>{assets.id}</td>
<td>{assets.serialNo}</td>
<td>{assets.assetTag}</td>
<td>{assets.name}</td>
<td>{assets.assignedTo}</td>
<td>{assets.statusType}</td>
<td>{assets.manufacturerName}</td>
<td>{assets.categoryName}</td>
<td>{assets.purchaseDate}</td>
<td>{assets.warranty}</td>
<td>{this.generateActionButtonInfo()}{this.generateActionButtonEdit()}</td>
</tr>
);
})
)
}
generateActionButtonInfo=()=>{
return(
<Button type="submit" value ="Info" variant="info" onClick={this.showInfo}>Info</Button>
)
}
generateActionButtonEdit=()=>{
return(
<Button type="submit" value ="addCategory" variant="secondary" onClick={this.handleEdit}>Edit</Button>
)
}
generateAssetTable(){
return(
<Table striped bordered hover>
<thead>{this.generateColumnHeader()}</thead>
<tbody>{this.generateRowsData()}</tbody>
</Table>
)
}
render(){
return(
<div>
<div className="container">
<div className="d-flex justify-content-center">
{this.generateAssetTable()}
</div>
</div>
</div>
);
}
}
export default ViewAssets;
You can make api calls inside the success callback of the previous api call , and in the final success callback, you can do a single setstate. You can also show the progress percentage using axios's onUploadProgress / onDownloadProgress .
For the final touch , you can have an error page if anything goes wrong , and render that if any issues during the api calls.