I'm a React newbie and I was following a tutorial on YouTube, which is at the time of writing this approximately 3 months old.
I got to this phase:
However then I ran into a problem. This is a piece of code that works so far:
function App() {
const [theme, colorMode] = useMode();
return (
<ColorModeContext.Provider value={colorMode}>
<ThemeProvider theme={theme}>
<CssBaseline />
<div className='app'>
{/* <Sidebar /> This is the const which causes the web to break for some reason */}
<main className='content'>
<Topbar />
{/* <Routes> */}
{/* <Route path='/' element={<Dashboard />} /> */}
{/* <Route path='/classification' element={<Classification />} /> */}
{/* <Route path='/timetable' element={<Timetable />} /> */}
{/* <Route path='/class' element={<Class />} /> */}
{/* <Route path='/profile' element={<Profile />} /> */}
{/* <Route path='/settings' element={<Settings />} /> */}
{/* <Route path='/notifications' element={<Notifications />} /> */}
{/* <Route path='/calendar' element={<Calendar />} /> */}
{/* </Routes> */}
</main>
</div>
</ThemeProvider>
</ColorModeContext.Provider>
);
}
export default App;
However if I uncomment the <Sidebar /> the page turns blank. As far as I tried to debug, it doesn't matter if the Sidebar file is empty or not, the page turns blank regardless.
As a React newbie, my knowledge is very limited so I haven't tried much aside of debugging. All I know is that the code in the file doesn't affect the error in any way. What I expected to happen is a sidebar to appear on the left with a couple of buttons and an image. Instead the page just turned blank. I assume this is not caused by some outdated dependencies since as I said, the code in the Sidebar file doesn't seem to affect this error. My assumption is a logical mistake I can't manage to find.
I'd love to get any sort of help with this. Furthermore, if anyone knows how to write this piece of code differently, with the same functionality (you can see in the linked video tutorial above), I will definitely be looking forward to seeing your advice. Thanks a bunch!
EDIT: This is the Sidebar file:
import { useState } from "react";
import { ProSidebar, Menu, MenuItem } from "react-pro-sidebar";
import { Box, IconButton, Typography, useTheme } from "#mui/material";
import { Link } from "react-router-dom";
import "react-pro-sidebar/dist/css/styles.css";
import { tokens } from "../../theme";
import HomeOutlinedIcon from "#mui/icons-material/HomeOutlined";
import PeopleOutlinedIcon from "#mui/icons-material/PeopleOutlined";
import ContactsOutlinedIcon from "#mui/icons-material/ContactsOutlined";
import ReceiptOutlinedIcon from "#mui/icons-material/ReceiptOutlined";
import PersonOutlinedIcon from "#mui/icons-material/PersonOutlined";
import CalendarTodayOutlinedIcon from "#mui/icons-material/CalendarTodayOutlined";
import HelpOutlineOutlinedIcon from "#mui/icons-material/HelpOutlineOutlined";
import BarChartOutlinedIcon from "#mui/icons-material/BarChartOutlined";
import PieChartOutlineOutlinedIcon from "#mui/icons-material/PieChartOutlineOutlined";
import TimelineOutlinedIcon from "#mui/icons-material/TimelineOutlined";
import MenuOutlinedIcon from "#mui/icons-material/MenuOutlined";
import MapOutlinedIcon from "#mui/icons-material/MapOutlined";
const Item = ({ title, to, icon, selected, setSelected }) => {
const theme = useTheme();
const colors = tokens(theme.palette.mode);
return (
<MenuItem
active={selected === title}
style={{
color: colors.grey[100],
}}
onClick={() => setSelected(title)}
icon={icon}
>
<Typography>{title}</Typography>
<Link to={to} />
</MenuItem>
);
};
const Sidebar = () => {
const theme = useTheme();
const colors = tokens(theme.palette.mode);
const [isCollapsed, setIsCollapsed] = useState(false);
const [selected, setSelected] = useState("Dashboard");
return (
<Box
sx={{
"& .pro-sidebar-inner": {
background: `${colors.primary[400]} !important`,
},
"& .pro-icon-wrapper": {
backgroundColor: "transparent !important",
},
"& .pro-inner-item": {
padding: "5px 35px 5px 20px !important",
},
"& .pro-inner-item:hover": {
color: "#868dfb !important",
},
"& .pro-menu-item.active": {
color: "#6870fa !important",
},
}}
>
<ProSidebar collapsed={isCollapsed}>
<Menu iconShape="square">
{/* LOGO AND MENU ICON */}
<MenuItem
onClick={() => setIsCollapsed(!isCollapsed)}
icon={isCollapsed ? <MenuOutlinedIcon /> : undefined}
style={{
margin: "10px 0 20px 0",
color: colors.grey[100],
}}
>
{!isCollapsed && (
<Box
display="flex"
justifyContent="space-between"
alignItems="center"
ml="15px"
>
<Typography variant="h3" color={colors.grey[100]}>
Project Romeo
</Typography>
<IconButton onClick={() => setIsCollapsed(!isCollapsed)}>
<MenuOutlinedIcon />
</IconButton>
</Box>
)}
</MenuItem>
{!isCollapsed && (
<Box mb="25px">
<Box display="flex" justifyContent="center" alignItems="center">
<img
alt="profile-user"
width="100px"
height="100px"
src={`../../assets/user.png`} // Database here for user profile picture or default picture?
style={{ cursor: "pointer", borderRadius: "50%" }}
/>
</Box>
<Box textAlign="center">
<Typography
variant="h2"
color={colors.grey[100]}
fontWeight="bold"
sx={{ m: "10px 0 0 0" }}
>
Vojtěch Král
</Typography>
<Typography variant="h5" color={colors.greenAccent[500]}>
Project Romeo Developer
</Typography>
</Box>
</Box>
)}
<Box paddingLeft={isCollapsed ? undefined : "10%"}>
<Item
title="Dashboard"
to="/"
icon={<HomeOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Typography
variant="h6"
color={colors.grey[300]}
sx={{ m: "15px 0 5px 20px" }}
>
Data
</Typography>
<Item
title="Manage Team"
to="/team"
icon={<PeopleOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Item
title="Contacts Information"
to="/contacts"
icon={<ContactsOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Item
title="Invoices Balances"
to="/invoices"
icon={<ReceiptOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Typography
variant="h6"
color={colors.grey[300]}
sx={{ m: "15px 0 5px 20px" }}
>
Pages
</Typography>
<Item
title="Profile Form"
to="/form"
icon={<PersonOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Item
title="Calendar"
to="/calendar"
icon={<CalendarTodayOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Item
title="FAQ Page"
to="/faq"
icon={<HelpOutlineOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Typography
variant="h6"
color={colors.grey[300]}
sx={{ m: "15px 0 5px 20px" }}
>
Charts
</Typography>
<Item
title="Bar Chart"
to="/bar"
icon={<BarChartOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Item
title="Pie Chart"
to="/pie"
icon={<PieChartOutlineOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Item
title="Line Chart"
to="/line"
icon={<TimelineOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
<Item
title="Geography Chart"
to="/geography"
icon={<MapOutlinedIcon />}
selected={selected}
setSelected={setSelected}
/>
</Box>
</Menu>
</ProSidebar>
</Box>
);
};
export default Sidebar;
Related
I would like to change the colors of each title={note.title} subheader={note.category} I have tried
const theme = createTheme ({
palette: {
category: {
color: blue
}
}
})
But that hasn't worked I have also tried inline
sx={{fontSize: 16,color: '#000000'}} again no luck.
How can I go about editing the color for those 2 sections?
<div>
<Card elevation={10} className={classes.test}>
<CardHeader
action={ // 200
<IconButton onClick={() => handleDelete(note.id)}>
<DeleteOutlined />
</IconButton>
}
title={note.title}
subheader={note.category}
/>
<CardContent>
<FormGroup>
<FormControlLabel sx={{fontSize: 16,color: '#000000'}} control={<Checkbox />} label={note.details} />
<FormControlLabel sx={{fontSize: 16,color: '#555555'}} control={<Checkbox />} label={note.details2} />
</FormGroup>
</CardContent>
</Card>
</div>
)
Full code here : https://github.com/Orelso/Project-notes
You can pass node in the title and subheader -
<CardHeader
action={ // 200
<IconButton onClick={() => handleDelete(note.id)}>
<DeleteOutlined />
</IconButton>
}
title={<span style={{fontSize: 16, color: "#000000"}}>{note.title}</span>}
subheader={<span style={{fontSize: 12, color: "#000000"}}>{note.category}</span>}
/>
On opening the sidebar the main content scroll does not work. Also some fields such as select options, search bar do not work when the sidebar is open. I have added the main content in the routes from where it is being loaded. The scroll, above listed functions work fine when the side-drawer is closed. I am relatively new to material ui + react and tried to workaround with some tips from other sources but I am stuck with this for a long time.
<>
<Box sx={{ display: "flex" }}>
<AppBar
sx={{ backgroundColor: "rgb(19, 71, 129)" }}
position="fixed"
className={classes.appBar}
>
<Toolbar align="center">
<IconButton
color="inherit"
onClick={handleMenuClick}
edge="start"
className={clsx(classes.menuButton)}
>
<MenuIcon />
</IconButton>
</Toolbar>
</AppBar>
<Drawer
className={classes.drawer}
variant="temporary"
open={open}
transitionDuration={{
enter: transitionDuration,
exit: transitionDuration,
}}
classes={{
paper: classes.drawerPaper,
}}
>
<Toolbar>
<IconButton
sx={{ marginLeft: "auto" }}
onClick={handleMenuClick}
edge="start"
className={clsx(classes.menuButton)}
>
<ChevronLeftIcon />
</IconButton>
</Toolbar>
<div className={classes.drawerContainer}>
{/* //Drawer Items */}
<DrawerItems open={open} isAdmin={isAdmin} />
</div>
{/* Logout */}
<LightTooltip title="Logout" placement="top">
<IconButton
sx={{ marginTop: "auto" }}
onClick={handleLogout}
color="error"
>
<ExitToAppIcon />
</IconButton>
</LightTooltip>
</Drawer>
{/* Routes for drawer components */}
<main
className={clsx(classes.content, {
[classes.contentShift]: open,
})}
>
<Routes>
<Route path="dashboard" element={<Dashboard />} />
<Route path="employees" element={<Employees />} />
<Route path="payroll" element={<Payroll />} />
<Route path="projects" element={<Projects />} />
<Route path="leaves" element={<Leaves />} />
<Route path="leavesemp" element={<LeavesEMP />} />
<Route path="empattendance" element={<EMPAttendance />} />
<Route path="hrattendance" element={<HRAttendance />} />
</Routes>
</main>
</Box>
</>
This is the style
drawerContainer: {
overflow: "auto",
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.sharp,
duration: transitionDuration,
}),
marginLeft: 0,
},
contentShift: {
transition: theme.transitions.create("margin", {
easing: theme.transitions.easing.easeOut,
duration: transitionDuration,
}),
marginLeft: drawerWidth,
},
I was in a hurry so I used a "persistent" mui drawer variant and solved the problem. I will still be looking to solve this particular problem though.
I am making a project using ChakraUI and React. So what I wanted to do is that to add some small animations in my project. Trying to implement the ChakraUI Fade component with react router dom, but I don't know how to use it properly.
So my sidebar has multiple options. These options may or may have submenus in it. What I wanted to do is that, when someone clicks in the option or any submenu, it will load the page after the Fade transition.
What I have done so far in my sidebar component
const SidebarTitle = () => {
return (
<>
<Box
width='200px'
height='160px'
textAlign='start'
bgColor='#473198'
px={5}
borderRadius={2}
>
<Text fontSize='2xl' color='white' fontFamily='Fjord One'>
some text
</Text>
</Box>
</>
);
};
export default function Sidebar() {
const [selectedSubMenu, setSelectedSubMenu] = useState("");
const handleClick = (title) => {
if (title === selectedSubMenu) {
setSelectedSubMenu("");
} else {
setSelectedSubMenu(title);
}
};
return (
<div>
<Box
display='flex'
justifyContent='flex-start'
alignItems='flex-start'
mb={10}
>
<Box>
<SidebarTitle />
{sidebarItems.map((items) => {
return (
<Box
width='200px'
textAlign='start'
cursor='pointer'
onClick={() => {
handleClick(items.title);
}}
fontFamily='Fjord One'
boxShadow='lg'
_hover={{
bgColor: "#1a2963",
color: "white",
}}
key={items.title}
>
<Link
to={items.url}
as={RouterLink}
width='100%'
_focus={{
boxShadow: "none",
}}
style={{ textDecoration: "none" }}
>
<Text fontSize='xl'>{items.title}</Text>
</Link>
<Collapse
in={items.title === selectedSubMenu}
transition={{ enter: { delay: 0.1 }, exit: { delay: 0.1 } }}
>
{items.subMenu?.map((item) => {
return (
<Box
bgColor='#e4e8e5'
boxShadow='md'
textAlign='start'
width='200px'
color='black'
_hover={{
bgColor: "#666666",
color: "white",
}}
key={item.title}
onClick={(event) => {
event.stopPropagation();
}}
>
<Link
to={item.url}
as={RouterLink}
width='100%'
_focus={{
boxShadow: "none",
}}
style={{ textDecoration: "none" }}
>
<Text fontFamily='Fjord One'>{item.title} </Text>
</Link>
</Box>
);
})}
</Collapse>
</Box>
);
})}
</Box>
<Box width='100%'>
<Routes>
<Route path='/' element={<Home />} />
<Route
path='about'
element={<about />}
/>
<Route
path='product'
element={<product />}
/>
<Route
path='dummy-link'
element={<dummy-link />}
/>
<Route path='dummy-link' element={<dummy-link />} />
<Route path='dummy-link' element={<dummy-link />} />
<Route path='dummy-link' element={<dummy-link />} />
<Route path='dummy-link' element={<dummy-link />} />
</Routes>
</Box>
</Box>
</div>
);
}
Can someone help me on how to implement the Fade transition in react router dom?
The naming conventions are off. Please ignore those.
Part of the code for the Appbar:
const useStyles = makeStyles((theme) => ({
root: {
flexGrow: 1
},
title: {
flexGrow: 1
}
}));
export default function Appp() {
const classes = useStyles();
const history = useHistory();
return (
<div className={classes.root}>
<Router>
<AppBar position="static" display="flex">
<Toolbar>
<Typography variant="h6" className={classes.title}>
Employee Management
</Typography>
<Button
variant="contained"
color="secondary"
className={classes.button}
>
<Link to="/emp">Fetch Employees</Link>
</Button>
<Switch>
<Route exact path="/emp" render={(props) => <App {...props} />} />
</Switch>
</Toolbar>
</AppBar>
<br/>
</Router>
</div>
);
}
The App component ("user" is JSON data received from an API call):
return (
<div className="App">
{user &&
user.map((singleUser) => {
return (
<SimpleCard
nam={singleUser.name}
uname={singleUser.username}
ph={singleUser.phone}
wb={singleUser.website}
></SimpleCard>
);
})}
</div>
);
}
The SimpleCard Component:
export default function SimpleCard(props) {
const classes = useStyles();
return (
<Card padding={6} style={{ backgroundColor: "red", display: "inline-block" }}>
<CardContent>
<Typography
className={classes.title}
color="textSecondary"
gutterBottom
>
<h1>{props.nam}</h1>
</Typography>
<Typography variant="h5" component="h5">
#{props.uname}
</Typography>
<Typography className={classes.pos} color="textPrimary">
adjective
</Typography>
<Typography variant="body2" component="p">
well meaning and kindly.
<br />
</Typography>
</CardContent>
</Card>
);
}
So when the Fetch Employees button is clicked, I want the cards with the information to show up. However they are just getting added in the Appbar and the UI is a mess.
return (
<div className={classes.root}>
<Router>
<AppBar position="static" display="flex">
<Toolbar>
<Typography variant="h6" className={classes.title}>
Employee Management
</Typography>
<Button
variant="contained"
color="secondary"
className={classes.button}
>
<Link to="/emp">Fetch Employees</Link>
</Button>
</Toolbar>
</AppBar>
<br/>
<Switch>
<Route exact path="/emp" render={(props) => <App {...props} />} />
</Switch>
</Router>
</div>
);
You just need to remove your navigator out of the bar
Context that I created to use useState across my component:
context.js:
const searchContext = React.createContext();
This is where I created a useState with searchText with initial state as an empty string.
Header.js:
import { useState } from "react";
import { searchContext } from "./context";
import { useSelector } from 'react-redux';
import Motherboard from "./Components/Motherboard";
function Header() {
const[searchText,setSearchText] = useState("");
const cart = useSelector(state => state.cart);
return (
<div
style={{ backgroundColor: "#191C27", paddingLeft: 0, paddingRight: 0 }}
>
<Navbar
variant="light"
expand="lg"
style={{ backgroundColor: "#191C27" }}
>
<Container>
<Navbar.Toggle aria-controls="navbarScroll">
<img src={options} alt="options" width="30px" />
</Navbar.Toggle>
<Navbar.Brand className="mr-auto" href="#">
<Link to='home'>
<img
className="logoIcon"
src={logo}
alt="logo"
style={{ width: 130 }}
/>
</Link>
</Navbar.Brand>
<Navbar.Collapse id="navbarScroll">
<Nav
className="ml-auto my-2 my-lg-0"
style={{ maxHeight: "100px", marginRight: "5%" }}
navbarScroll
>
<Nav.Link>
<Link to='/motherboard' className="links">
Motherboard
</Link>
</Nav.Link>
<Nav.Link onClick={(e) => e.preventDefault()}>
<Link to='/processor' className="links">
Processor
</Link>
</Nav.Link>
<Nav.Link>
<Link to='/ram' className="links">
RAM
</Link>
</Nav.Link>
<Nav.Link>
<Link to='/hdd' className="links">
HDD
</Link>
</Nav.Link>
<Nav.Link>
<Link to='/graphic' className="links">
Cabinet
</Link>
</Nav.Link>
</Nav>
</Navbar.Collapse>
<Form className="d-flex" style={{ marginRight: "2%" }}>
<searchContext.Provider value={searchText}>
<Motherboard></Motherboard>
</searchContext.Provider>
<FormControl
type="search"
placeholder="Search"
onChange={event => {setSearchText(event.target.value)}}
className="mr-2"
aria-label="Search"
style={{background:'transparent', borderRadius:0, color:'white'}}
/>
</Form>
Now I tried using my useContext and called the useState value searchText here in Motherboard component. But getting some undefined errors while running.
Motherboard.js:
import {searchContext} from '../context'
const dummy = Array.from(Array(10));
function Motherboard(props) {
let context = useContext(searchContext);
const [loading, setLoading] = React.useState(true);
// const [products, setProducts] = React.useState([]);
const products = useSelector((state) => state.products);
const dispatch = useDispatch();
useEffect(() => {
axios
.post("/product?limit=50&page=1&category=motherboard")
.then((res) => {
console.log(res, "res");
dispatch({
type: actionTypes.GET_PRODUCTS,
payload: res.data.products,
});
setLoading(false);
})
.catch((err) => {
setLoading(false);
console.log(err);
});
}, []);
const styleCol = {
backgroundColor: "#0F0F13",
};
if (loading) {
return (
<div className='loadDiv'>
<ClipLoader size="150" color="white" style={{marginTop: -200}}/>
</div>
);
}
return (
<div className="filterDiv">
<Banner />
<Container fluid="md">
<Row>
<Col lg={3} style={styleCol} className="colFilter">
<div>
<div style={{ backgroundColor: "#191C27" }}>
<Accordion>
<AccordionSummary
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography>SORT BY PRICE</Typography>
</AccordionSummary>
<div className="filterDiv">
<AccordionDetails>
<FormControl component="fieldset">
<RadioGroup aria-label="gender" name="gender1">
<FormControlLabel
value="hightolow"
control={<Radio />}
label="Highest to Lowest"
className="radioBtn"
/>
<FormControlLabel
value="lowtohigh"
control={<Radio />}
label="Lowest to Highest"
className="radioBtn"
/>
</RadioGroup>
</FormControl>
</AccordionDetails>
</div>
</Accordion>
</div>
<div style={{ backgroundColor: "#191C27" }}>
<Accordion>
<AccordionSummary
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography className="heading">SUB CATEGORY</Typography>
</AccordionSummary>
<div className="filterDiv">
<AccordionDetails>
<FormControl component="fieldset">
<RadioGroup aria-label="processor" name="prcocessor">
<FormControlLabel
value="hightolow"
control={<Radio />}
label="INTEL"
className="radioBtn"
/>
<FormControlLabel
value="lowtohigh"
control={<Radio />}
label="AMD"
className="radioBtn"
/>
</RadioGroup>
</FormControl>
</AccordionDetails>
</div>
</Accordion>
</div>
</div>
</Col>
<Col
xs={12}
lg={9}
sm={12}
md={12}
style={{ backgroundColor: "#0F0F13", paddingTop: 27 }}
>
<Row>
{products.filter((product) => {
if(context.searchText == '') {
return product
}
else if(product.productName.toLowerCase.includes(context.searchText.toLowerCase())){
return product
}}).map((product, index) => {
return (
<Col key={index} lg={4} md={6} xs={12} sm={6}>
<div
you can try to define value as object. the error is probably due to the value not being an object
<searchContext.Provider value={{ searchText }}>
<Motherboard></Motherboard>
</searchContext.Provider>
As you wrote context.searchText, you have to store an object inside the value of the provider:
<searchContext.Provider value={{ searchText }}>
<Motherboard />
</searchContext.Provider>
use context instead of context.searchText in MotherBoard.js because you are passing a string as the value in the provider so when call the context using useContext , it gives the latest value of the provider which is what you typed in the search box.