I have some menu items I want to show according to user roles. I have 2 user roles form the database (1 for admin and 0 for normal user). But my code always return the menu items for normal user even if its an admin who is logged in.
I am also storing user details in a useContext and calling them on every component
Kindly Help
My Code
import React, { Component } from "react";
import { Link } from "react-router-dom";
import "./Menubar.css";
import { UserContext } from "../../UserContext";
const Menubar = () => {
const user = React.useContext(UserContext);
console.warn(user.role)
return (
<div>
<div className="appBottomMenu">
{user.role === 1 ? (
<Link to="/admin/home" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-home"></i>
</div>
</Link>
) : (
<Link to="/" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-home"></i>
</div>
</Link>
)}
{user.role === 1 ? (
<Link className="item" to="/admin/farmers">
<div className="col">
<i className="fi fi-rr-users"></i>
</div>
</Link>
) : (
<Link to="/area" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-marker"></i>
</div>
</Link>
)}
<Link to="/community" className="item">
<div className="col">
<i className="fi fi-rr-browser"></i>
</div>
</Link>
{user.role === 1 ? (
<Link className="item" to="/admin/farms">
<div className="col">
<i className="fi fi-rr-users"></i>
</div>
</Link>
) : (
<Link to="/shop" className="item">
<div className="col">
<i className="fi fi-rr-shopping-cart"></i>
</div>
</Link>
)}
<Link to="/profile" className="item">
<div className="col">
<i className="fi fi-rr-user"></i>
</div>
</Link>
</div>
</div>
);}
export default Menubar;
One potential way to force an update on the page on context updates is to utilize the useEffect and useState hooks in conjunction with your useContext. Here is an example, I hope this helps.
For example:
import React, { Component, useEffect, useContext, useState } from "react";
import { Link } from "react-router-dom";
import "./Menubar.css";
import { UserContext } from "../../UserContext";
const Menubar = () => {
const { user } = useContext(UserContext);
const [menuContext, setMenuContext] = useState(user);
const handleSetMenuContext = (updatedMenuContext) => {
setMenuContext(updatedMenuContext);
};
useEffect(() => {
handleSetMenuContext(user);
}, [user]);
return menuContext?.role && (
<div>
<div className="appBottomMenu">
{menuContext.role === 1 ? (
<Link to="/admin/home" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-home"></i>
</div>
</Link>
) : (
<Link to="/" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-home"></i>
</div>
</Link>
)}
{menuContext.role === 1 ? (
<Link className="item" to="/admin/farmers">
<div className="col">
<i className="fi fi-rr-users"></i>
</div>
</Link>
) : (
<Link to="/area" className="item" tabIndex="1">
<div className="col">
<i className="fi fi-rr-marker"></i>
</div>
</Link>
)}
<Link to="/community" className="item">
<div className="col">
<i className="fi fi-rr-browser"></i>
</div>
</Link>
{menuContext.role === 1 ? (
<Link className="item" to="/admin/farms">
<div className="col">
<i className="fi fi-rr-users"></i>
</div>
</Link>
) : (
<Link to="/shop" className="item">
<div className="col">
<i className="fi fi-rr-shopping-cart"></i>
</div>
</Link>
)}
<Link to="/profile" className="item">
<div className="col">
<i className="fi fi-rr-user"></i>
</div>
</Link>
</div>
</div>
);
}
export default Menubar;
Related
This is the code where I have my addtocart function,
import React from 'react'
import './Body.css'
import { useState } from 'react'
// import './Cart.js'
export default function Pricetag(props) {
const [count, setCartCount] = useState(0)
return (
<div>
<div className="cart">
<i class="fa-solid fa-cart-shopping"></i>
<div id="number">=</div>
</div>
<div className="card1">
<div className="image">
<img src={props.images} alt="" className='card-image' />
</div>
<div className="content">
<div className="name">
{props.name}
</div>
</div>
<div className="button">
<button className='btn no1' id='cartbutton' onClick={() => setCartCount( count +1)} >
{/* <a id="cart" href="https://wa.me/<919650988301>" target='_blank' rel="noreferrer" className='no1'>Add to cart</a></button> */}
Add to cart </button>
</div>
</div>
<script ></script>
</div>
)
}
When I do,
number.innerHTML+=`${items}`
instead of
number.innerHTML=`${items}`
then the numbers are concatenated like strings.
Otherwise, nothing is happening, what is wrong here?
Can you suggest me some edits in the same code.
As you are using React framework you should use React hooks
Here is an example:
import React, { useState } from 'react'
import './Body.css'
// import './Cart.js'
export default function Pricetag(props) {
const [cartCount, setCartCount] = useState(0)
return (
<div>
<div className="cart">
<i class="fa-solid fa-cart-shopping"></i>
<div id="number">={cartCount}</div>
</div>
<div className="card1">
<div className="image">
<img src={props.images} alt="" className='card-image' />
</div>
<div className="content">
<div className="name">
{props.name}
</div>
</div>
<div className="button">
<button className='btn no1' id='cartbutton' onClick={() => setCartCount(cartCount +1))} >
{/* <a id="cart" href="https://wa.me/<919650988301>" target='_blank' rel="noreferrer" className='no1'>Add to cart</a></button> */}
Add to cart </button>
</div>
</div>
</div>
)
}
Working on codesandbox
I want to make the Material UI Input stick at the top when scrolling, I have a modal an its content is the search input and the results.
I used overflow-y: scroll; in <div className="modal-content"> and used position: sticky; in <OutlinedInput className="SearchInput" /> but then the search and the results scroll together which I don't want it to, I want only the result to scroll.
Then I removed the overflow-y: scroll; from in <div className="modal-content"> and put it in <div className="card" key={post._id}> but then the results went outside the modal borders as in the Image down below
The Code:
return (
<>
<button onClick={toggleModal} className="btn-modal">
<SearchIcon />
</button>
{modal && (
<div className="modal">
<div onClick={toggleModal} className="overlay"></div>
<div className="modal-content">
<div className="searchBar">
<div style={{ padding: 20 }}>
<div font-size="20px" className="searchTry">Search</div>
<OutlinedInput
className="SearchInput"
placeholder='Search...'
onChange={(e) => searchItems(e.target.value)}
endAdornment={
<InputAdornment>
<SearchIcon />
</InputAdornment>
}
/>
<div style={{ marginTop: 20 }}>
{searchInput.length > 0 ? (
filteredResults.map((post) => {
return (
<div className="card" key={post._id}>
<div className="card-content">
<Link to={`/post/${post._id}`} className="link">
<h2 className="results-title">
{post.title}
</h2>
<ol className="card-username">
{post.username}
</ol>
</Link>
</div>
</div>
)
})
) : (
APIData.map((post) => {
return (
<div className="card" key={post._id}>
<div className="card-content">
<Link to={`/post/${post._id}`} className="link">
<h2 className="card-name">
{post.title}
</h2>
<ol className="card-username">
{post.username}
</ol>
</Link>
</div>
</div>
)
})
)}
</div>
</div>
</div>
<button className="close-modal" onClick={toggleModal}>
<CloseIcon />
</button>
</div>
</div>
)}
</>
);
Could someone maybe explain why my map doesn't work in the template.
I tried 4 hours, but i didn't get a useful solution.
The render() works bevor i fetched all data from firebase
If i try to render the map again by using the setState Hook or in my case the setsalesList hook the templet doesn't render again.
import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import NavBar from "./NavBar";
import { db } from "../firebase";
import { useAuth } from "../contexts/AuthContext";
const Sales = () => {
const [isLoading, setIsLoading] = useState(true);
const [salesList, setSalesList] = useState([]);
const { currentUser } = useAuth();
async function setupProject() {
let salesDataList = [];
await db
.collection("users")
.doc(currentUser.uid)
.get()
.then((userItemData) => {
const userItem = userItemData.data();
db.collection("projects")
.doc(userItem.project[0])
.get()
.then((projectData) => {
db.collection("sales")
.where("project", "==", projectData.id)
.get()
.then((sales) => {
sales.forEach((sale) => {
sale
.data()
.customer.get()
.then((customer) => {
let salesData = {
key: sale.id,
name: customer.data().name,
sold: sale.data().sold,
date:
new Date(sale.data().time.toDate()).getDate() +
"." +
new Date(sale.data().time.toDate()).getMonth() +
"." +
+new Date(sale.data().time.toDate()).getFullYear(),
};
salesDataList.push(salesData);
console.log(salesDataList);
});
});
setSalesList(salesDataList);
})
.finally(() => {});
});
});
setIsLoading(false);
}
useEffect(() => {
setupProject();
}, []);
return (
<>
<NavBar />
<div className="header header-fixed header-logo-center">
<a className="header-title">Verkäufe</a>
<a href="https://huehnerpi.de/customer" className="header-icon">
<i className="fas fa-user" />
</a>
<a
href="https://huehnerpi.de/sales/newSale"
className="header-icon header-icon-4"
>
<i className="fas fa-plus" />
</a>
</div>
{isLoading ? (
<div className="page-content header-clear-medium">
<div
className="content mt-0"
style={{
marginBottom: 16,
marginLeft: 16,
marginRight: 16,
}}
>
<p>Lädt...</p>
</div>
</div>
) : (
<div className="page-content header-clear-medium">
<div
className="card card-style"
style={{
marginBottom: "16px",
}}
>
<div className="content mb-0">
<div className="input-style input-style-always-active has-borders no-icon">
<select
id="dropdownStatus"
style={{
color: "darkslategray",
}}
>
<option value="all">Alle Status</option>
</select>
<span>
<i className="fa fa-chevron-down" />
</span>
<i className="fa fa-check disabled valid color-green-dark" />
<em />
</div>
<div className="input-style input-style-always-active has-borders no-icon">
<select
id="dropdownCustomer"
style={{
color: "darkslategray",
}}
>
<option value="all">Alle Käufer</option>
</select>
<span>
<i className="fa fa-chevron-down" />
</span>
<i className="fa fa-check disabled valid color-green-dark" />
<em />
</div>
</div>
</div>
{console.log(salesList.length)}
{salesList.map((saleItem) => (
<a
key={saleItem.key}
className="card card-style mb-3 filterDiv"
style={{ display: "block" }}
>
<div className="content">
<h3>
{saleItem.name} - {saleItem.sold} Eier
<span data-menu="menu-contact-2" style={{ float: "right" }}>
<span className="icon icon-xxs rounded-sm shadow-sm me-1 bg-red-dark">
<i className="fas fa-times" />
</span>
</span>
<span style={{ float: "right" }}>
<span className="icon icon-xxs rounded-sm shadow-sm me-1 bg-blue-dark">
<i className="fas fa-pen" />
</span>
</span>
</h3>
<div className="row mb-n2 color-theme">
<div className="col font-10 text-start">
<span className="badge bg-green-dark color-white font-10 mt-2">
Bezahlt
</span>
</div>
<div className="col font-10 text-end opacity-30">
<i className="fa fa-calendar pe-2" />
12.12.2020 <span className="copyright-year" />
</div>
</div>
</div>
</a>
))}
</div>
)}
</>
);
};
export default Sales;
In this way it worked now for me!
I set the state after the last iteration of my foreach
import {Link} from "react-router-dom";
import NavBar from "./NavBar";
import {db} from "../firebase"
import {useAuth} from "../contexts/AuthContext";
const Sales = () => {
const [isLoading, setIsLoading] = useState(true);
const [salesList, setSalesList] = useState([]);
const { currentUser } = useAuth();
function setupProject() {
let salesDataList = [];
db.collection("users").doc(currentUser.uid).get()
.then(userItemData => {
const userItem = userItemData.data();
db.collection("projects").doc(userItem.project[0]).get()
.then(projectData => {
db.collection("sales").where("project", "==", projectData.id).get()
.then((sales) => {
let i = 0;
sales.forEach((sale) => {
sale.data().customer.get()
.then(customer => {
let salesData = {
key: sale.id,
name: customer.data().name,
sold: sale.data().sold,
date: new Date(sale.data().time.toDate()).getDate() + "." + new Date(sale.data().time.toDate()).getMonth() + "." + + new Date(sale.data().time.toDate()).getFullYear(),
};
salesDataList.push(salesData)
if (sales.size -1 === i++) {
setSalesList(salesDataList);
setIsLoading(false);
}
})
});
});
});
});
}
useEffect(() => {
setupProject();
}, []);
return(
<>
<NavBar />
<div className="header header-fixed header-logo-center">
<a className="header-title">Verkäufe</a>
<i className="fas fa-user"/>
<i className="fas fa-plus"/>
</div>
{isLoading ? (
<div className="page-content header-clear-medium">
<div className="content mt-0" style={{
marginBottom: 16,
marginLeft: 16,
marginRight: 16
}}>
<p>Lädt...</p>
</div>
</div>
) : (
<div className="page-content header-clear-medium">
<div className="card card-style" style={{
marginBottom: "16px"
}}>
<div className="content mb-0">
<div className="input-style input-style-always-active has-borders no-icon">
<select id="dropdownStatus" style={{
color: "darkslategray"
}}>
<option value="all">Alle Status</option>
</select>
<span><i className="fa fa-chevron-down"/></span>
<i className="fa fa-check disabled valid color-green-dark"/>
<em/>
</div>
<div className="input-style input-style-always-active has-borders no-icon">
<select id="dropdownCustomer" style={{
color: "darkslategray"
}}>
<option value="all">Alle Käufer</option>
</select>
<span><i className="fa fa-chevron-down"/></span>
<i className="fa fa-check disabled valid color-green-dark"/>
<em/>
</div>
</div>
</div>
{salesList.length > 0 && console.log(salesList.length)}
{salesList.map(saleItem => (
<a key={saleItem.key} className="card card-style mb-3 filterDiv" style={{display: "block"}}>
<div className="content">
<h3>{saleItem.name} - {saleItem.sold} Eier
<span data-menu="menu-contact-2" style={{float: "right"}}>
<span className="icon icon-xxs rounded-sm shadow-sm me-1 bg-red-dark">
<i className="fas fa-times"/>
</span>
</span>
<span style={{float: "right"}}>
<span className="icon icon-xxs rounded-sm shadow-sm me-1 bg-blue-dark">
<i className="fas fa-pen"/>
</span>
</span>
</h3>
<div className="row mb-n2 color-theme">
<div className="col font-10 text-start">
<span className="badge bg-green-dark color-white font-10 mt-2">Bezahlt</span>
</div>
<div className="col font-10 text-end opacity-30">
<i className="fa fa-calendar pe-2"/>12.12.2020 <span className="copyright-year"/>
</div>
</div>
</div>
</a>
))}
</div>
)}
</>
);
}
export default Sales;```
I want to add active class to the parent element of the div, but the problem is this code is adding on double click not on single click, how to fix this.
The below code is for the sidebar which I want to show on my website, everything is fine but the problem is the handleActiveClass function is not working on single click.
import React from 'react';
import { Link } from 'react-router-dom';
import './Sidebar.css';
const Sidebar = ({ sidebarOpen, closeSidebar, handleLogout }) => {
let logoUrl = JSON.parse(localStorage.getItem('app_icon'));
const handleActiveClass = (e) => {
e.target.parentElement.classList.toggle('active_menu_link');
};
return (
<div id='sidebar' className={sidebarOpen ? 'sidebar-responsive' : ''}>
<div className='sidebar_title'>
<div className='sidebar_img'>
<img src={`https://stucharge.bakersbrisk.com${logoUrl}`} alt='logo' />
<h1>Admin Panel</h1>
</div>
<i className='fa fa-times' id='sidebaricon' onClick={closeSidebar}></i>
</div>
<div className='sidebar_menu'>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fa fa-home'></i>
<Link to='/home'>Dashboard</Link>
</div>
<h2>MNG</h2>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fas fa-user-circle'></i>
<Link to='/profile'>Profile </Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fas fa-book'></i>
<Link to='/subjects'>Subjects </Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fa fa-graduation-cap'></i>
<Link to='/courses'>Courses</Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fas fa-book-open'></i>
<Link to='/notes'>Notes</Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fas fa-chalkboard-teacher'></i>
<Link to='/class'>Online Class</Link>
</div>
<div className='sidebar_link ' onClick={(e) => handleActiveClass(e)}>
<i className='fa fa-handshake-o'></i>
<Link to='/contact'>Contact Developer</Link>
</div>
<h2>LEAVE</h2>
<div className='sidebar_logout'>
<i className='fa fa-power-off'></i>
<Link to='/' onClick={handleLogout}>
Log out
</Link>
</div>
<div
className='dev'
style={{ position: 'absolute', bottom: '20px', left: '8px' }}
>
<h3 style={{ color: '#51c4d3' }}>
Developed by{' '}
<i
className='far fa-thumbs-up'
style={{ fontSize: '1.6rem', marginLeft: '4px' }}
></i>
</h3>
<h2 style={{ color: '#b0efeb' }}>Codeven Solution</h2>
</div>
</div>
</div>
);
};
export default Sidebar;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
This code might not run here, but you can understand it as i have pasted the whole code.
I have a question regarding preventing duplicates from being added to
cart while using firebase as back-end.
It should be straight forward but for some reason, nothing I try is working.
const { products } = this.props;
return (
<div>
{products === undefined ? (
<p>Loading......</p>
) : (
products.map(val => {
return (
<div key={val.id} className="row">
<div className="col-sm-6">
<div className="card-body">
<img src={val.url} className="img-fluid" alt="Responsive" />
<h5 className="card-title">{val.name}</h5>
<h6 className="card-subtitle mb-2 text-muted">
{val.price}
</h6>
<button
className=" "
style={{
float: "right",
marginBottom: "1px",
width: "100%"
}}
onClick={() => this.submit(val)}
>
<i className="fas fa-cart-plus" />
</button>
</div>
</div>
</div>
);
})
)}
</div>
);