How to change the content when clicked on different items.
I have two different archives (Home.js and Sidebar.js), in Sidebar I declare the items, but in Home, I put some buttons. But I don't know how to pass the information that I want to change between the items listed in my sidebar.
I am using this Drawer example (https://material-ui.com/demos/drawers/#persistent-drawer).
Project Running
in my app.js i have
import React, { Component } from 'react';
import Footer from './componets/Footer';
import Home from './componets/Home';
import store from './store'
import { Provider } from 'react-redux';
class App extends Component {
render() {
return (
<Provider store={store}>
<div className="content">
<Drawer/>
<Home/>
<Footer/>
</div>
</Provider>
);
}
}
export default App;
In my css file:
.conteudo{
display: grid;
grid-template-areas:
'home home home home'
'home home home home'
'footer footer footer footer'
}
I got a way to do it. But for every button in my drawer, i need to create a function that puts a number in my value. Have a way to declare one function and that every button in my class pass a number to my value?
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { withStyles } from '#material-ui/core/styles';
import Drawer from '#material-ui/core/Drawer';
import CssBaseline from '#material-ui/core/CssBaseline';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import List from '#material-ui/core/List';
import Typography from '#material-ui/core/Typography';
import Divider from '#material-ui/core/Divider';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import ChevronLeftIcon from '#material-ui/icons/ChevronLeft';
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
import Button from '#material-ui/core/Button'
import HomeIcon from '#material-ui/icons/Home'
import MeetingRoomIcon from '#material-ui/icons/MeetingRoom'
const drawerWidth = 240;
function Conteudo(props){
return(
<Typography component='div'>
{props.children}
</Typography>
)
}
Conteudo.propTypes ={
children: PropTypes.node.isRequired,
};
const styles = theme => ({
root: {
display: 'flex',
},
appBar: {
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
},
menuButton: {
marginLeft: 12,
marginRight: 20,
},
hide: {
display: 'none',
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
drawerHeader: {
display: 'flex',
alignItems: 'center',
padding: '0 8px',
...theme.mixins.toolbar,
justifyContent: 'flex-end',
},
content: {
flexGrow: 1,
padding: theme.spacing.unit * 3,
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: -drawerWidth,
},
contentShift: {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
},
});
class PersistentDrawerLeft extends React.Component {
state = {
open: false,
value: 0
};
handleDrawerOpen = () => {
this.setState({ open: true });
};
handleDrawerClose = () => {
this.setState({ open: false });
};
checkEvent = () => {
this.setState({value : 1})
console.log({value : 1})
}
checkEvent1 = () => {
this.setState({value : 0})
console.log({value : 0})
}
handleChange = (event, value) => {
this.setState({ value })
console.log(value)
}
render() {
const { classes, theme } = this.props;
const { open } = this.state;
const { value } = this.state;
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
position="fixed"
className={classNames(classes.appBar, {
[classes.appBarShift]: open,
})}
>
<Toolbar disableGutters={!open}>
<IconButton
color="inherit"
aria-label="Open drawer"
onClick={this.handleDrawerOpen}
className={classNames(classes.menuButton, open && classes.hide)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" color="inherit" noWrap>
Drawer
</Typography>
</Toolbar>
</AppBar>
<Drawer
value ={value}
className={classes.drawer}
variant="persistent"
anchor="left"
open={open}
classes={{
paper: classes.drawerPaper,
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={this.handleDrawerClose}>
<ChevronLeftIcon />
</IconButton>
</div>
<Divider />
<List>
<ListItem button onClick={this.checkEvent1} onChange={this.handleChange}>
<ListItemIcon>
<HomeIcon/>
</ListItemIcon>
<ListItemText primary='Central'/>
</ListItem>
<ListItem button onClick={this.checkEvent} onChange={this.handleChange}>
<ListItemIcon>
<MeetingRoomIcon/>
</ListItemIcon>
<ListItemText primary='BedRoom'/>
</ListItem>
</List>
<Divider />
</Drawer>
<main
className={classNames(classes.content, {
[classes.contentShift]: open,
})}
>
<div className={classes.drawerHeader} onChange={this.handleChange}/>
{value === 0 && <Conteudo> <Button variant="contained" color="primary">Default</Button> </Conteudo>}
{value === 1 && <Conteudo><Button variant="contained" color="secondary">Default</Button> </Conteudo>}
{value === 2 && <Conteudo><Button variant="contained" color="danger">Default</Button> </Conteudo>}
</main>
</div>
);
}
}
PersistentDrawerLeft.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired,
};
export default withStyles(styles, { withTheme: true })(PersistentDrawerLeft);
Related
I want to show only one component inside a white container that clicked but it is showing all components . how can I create an admin panel with fine routing ???
Like other admin panel, i just want to show proper routing But in my case, both components are displaying
App.js, main file
import { BrowserRouter, Route, Switch } from "react-router-dom"
import Home from "./Components/Home/Home"
import CreateAccount from "./Components/Create-Account/CreateAccount"
import PostRequest from "./Components/Post-request/PostRequest"
import New from "./new"
const App = () => {
return (
<BrowserRouter>
<Home />
<Route exact path="/" component={New} />
<Switch >
<Route exact path="/createAccount" component={CreateAccount} />
<Route exact path="/postRequests" component={PostRequest} />
</Switch>
</BrowserRouter>
)
}
export default App
And the Home page Component
import React from 'react';
import clsx from 'clsx';
import "./home.css"
import PostRequest from "../Post-request/PostRequest"
import CreateAccount from "../Create-Account/CreateAccount"
import { SidebarData } from "./sideBarData"
import { Link } from "react-router-dom"
import { makeStyles, useTheme } from '#material-ui/core/styles';
import Drawer from '#material-ui/core/Drawer';
import CssBaseline from '#material-ui/core/CssBaseline';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import List from '#material-ui/core/List';
import Typography from '#material-ui/core/Typography';
import Divider from '#material-ui/core/Divider';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import ChevronLeftIcon from '#material-ui/icons/ChevronLeft';
import ChevronRightIcon from '#material-ui/icons/ChevronRight';
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
appBar: {
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
width: `calc(100% - ${drawerWidth}px)`,
marginLeft: drawerWidth,
transition: theme.transitions.create(['margin', 'width'], {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
},
menuButton: {
marginRight: theme.spacing(2),
},
hide: {
display: 'none',
},
drawer: {
width: drawerWidth,
flexShrink: 0,
},
drawerPaper: {
width: drawerWidth,
},
drawerHeader: {
display: 'flex',
alignItems: 'center',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
justifyContent: 'flex-end',
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: -drawerWidth,
},
contentShift: {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
marginLeft: 0,
},
}));
export default function PersistentDrawerLeft() {
const classes = useStyles();
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: open,
})}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
className={clsx(classes.menuButton, open && classes.hide)}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" noWrap>
Master Panel
</Typography>
</Toolbar>
</AppBar>
<Drawer
className={classes.drawer}
variant="persistent"
anchor="left"
open={open}
classes={{
paper: classes.drawerPaper,
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'ltr' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
</IconButton>
</div>
<Divider />
<List>
<ul>
<h2>Admin</h2>
{SidebarData.map((item, index) => {
return (
<div>
<li key={index} className={item.cName}>
<Link className="textClass" to={item.path}>
<div className="listItem_Alignment container">
<span>{item.icon}</span>
<span className="titleLeftMargin">{item.title}</span>
</div>
</Link>
</li>
</div>
)
})}
</ul>
</List>
<Divider />
</Drawer>
<main
className={clsx(classes.content, {
[classes.contentShift]: open,
})}
>
<div className={classes.drawerHeader} />
<CreateAccount />
<PostRequest />
</main>
</div>
);
}
You can use nested routing for your admin panel. You take reference of below link.
Nested routing example
I am using mini variant drawer from material-ui official website
https://material-ui.com/components/drawers/#drawer
I am trying to convert into class component, but alot of issues, craches comes up. Some of them are hooks related and occurs through node modules.
Can any body have used this component in class component
import React from 'react'
import clsx from 'clsx'
import {
createStyles,
makeStyles,
useTheme,
Theme
} from '#material-ui/core/styles'
import Drawer from '#material-ui/core/Drawer'
import AppBar from '#material-ui/core/AppBar'
import Toolbar from '#material-ui/core/Toolbar'
import List from '#material-ui/core/List'
import CssBaseline from '#material-ui/core/CssBaseline'
import Typography from '#material-ui/core/Typography'
import Divider from '#material-ui/core/Divider'
import IconButton from '#material-ui/core/IconButton'
import MenuIcon from '#material-ui/icons/Menu'
import ChevronLeftIcon from '#material-ui/icons/ChevronLeft'
import ChevronRightIcon from '#material-ui/icons/ChevronRight'
import ListItem from '#material-ui/core/ListItem'
import ListItemIcon from '#material-ui/core/ListItemIcon'
import ListItemText from '#material-ui/core/ListItemText'
import InboxIcon from '#material-ui/icons/MoveToInbox'
import MailIcon from '#material-ui/icons/Mail'
const drawerWidth = 240
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
display: 'flex'
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
backgroundColor: 'transparent',
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
})
},
appBarShift: {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
})
},
menuButton: {
marginRight: 36
},
hide: {
display: 'none'
},
drawer: {
width: drawerWidth,
flexShrink: 0,
whiteSpace: 'nowrap'
},
drawerOpen: {
width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
})
},
drawerClose: {
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
overflowX: 'hidden',
width: theme.spacing(7) + 1,
[theme.breakpoints.up('sm')]: {
width: theme.spacing(9) + 1
}
},
toolbar: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar
},
content: {
flexGrow: 1,
padding: theme.spacing(3)
}
})
)
export default function MiniDrawer () {
const classes = useStyles()
const theme = useTheme()
const [open, setOpen] = React.useState(true)
const handleDrawerOpen = () => {
setOpen(true)
}
const handleDrawerClose = () => {
console.log('close clicked =')
setOpen(false)
console.log('open =', open)
}
return (
<div className={classes.root}>
<CssBaseline />
<AppBar
position='fixed'
className={clsx(classes.appBar, {
[classes.appBarShift]: open
})}
>
<Toolbar>
<IconButton
color='inherit'
aria-label='open drawer'
onClick={handleDrawerOpen}
edge='start'
className={clsx(classes.menuButton, {
[classes.hide]: open
})}
>
<MenuIcon />
</IconButton>
<Typography variant='h6' noWrap>
Mini variant drawer
</Typography>
</Toolbar>
</AppBar>
<Drawer
variant='permanent'
className={clsx(classes.drawer, {
[classes.drawerOpen]: open,
[classes.drawerClose]: !open
})}
classes={{
paper: clsx({
[classes.drawerOpen]: open,
[classes.drawerClose]: !open
})
}}
>
<div className={classes.toolbar}>
<IconButton onClick={handleDrawerClose}>
{theme.direction === 'rtl' ? (
<ChevronRightIcon />
) : (
<ChevronLeftIcon />
)}
</IconButton>
</div>
<Divider />
<List>
{['Inbox', 'Starred', 'Send email', 'Drafts'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
<Divider />
<List>
{['All mail', 'Trash', 'Spam'].map((text, index) => (
<ListItem button key={text}>
<ListItemIcon>
{index % 2 === 0 ? <InboxIcon /> : <MailIcon />}
</ListItemIcon>
<ListItemText primary={text} />
</ListItem>
))}
</List>
</Drawer>
<main className={classes.content}>
<div className={classes.toolbar} />
<Typography paragraph></Typography>
<Typography paragraph></Typography>
</main>
</div>
)
}
You cannot use hooks in a class component. Create a state property in your class and use it instead.
From react docs: Converting a Function to a Class
You can convert a function component like Clock to a class in five steps:
Create an ES6 class, with the same name, that extends React.Component.
Add a single empty method to it called render().
Move the body of the function into the render() method.
Replace props with this.props in the render() body.
Delete the remaining empty function declaration.
class Clock extends React.Component {
constructor(props) {
super(props);
this.state = {date: new Date()};
}
render() {
return (
<div>
<h1>Hello, world!</h1>
<h2>It is {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
I am new to react js and i'm trying to create a dashboard layout where i want to render a sidebar(which will be common in all the routes) and based upon the click event of sidebar items i want to render different component. Although i have achieved this, but in first instance the sidebar is present with the loaded component but once i refresh the page, only the newly loaded component remains on the page and sidebar is vanished.
//This is my main page code;
import React, { Component } from 'react';
import './Dashboard.css'
import Header from "../Header/Header";
import Footer from "../Footer/Footer";
import Sidebar from "../SideBar/Sidebar";
import Charts from "../Charts/Charts";
import About from "../About/About"
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
class Dashboard extends Component {
constructor(props) {
super(props)
}
render() {
// this.state.aboutComponent = this.props.aboutComponent;
return (
<Router>
<div>
<Sidebar></Sidebar>
<Switch>
<Route exact path={"/"} component={Charts} />
<Route exact path={"/about"} component={About} />
</Switch>
<Footer></Footer>
</div>
</Router>
)
}
}
export default Dashboard
import React from 'react';
import clsx from 'clsx';
import './Sidebar.css';
import { makeStyles, useTheme } from '#material-ui/core/styles';
import Drawer from '#material-ui/core/Drawer';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import List from '#material-ui/core/List';
import Divider from '#material-ui/core/Divider';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import DeleteIcon from '#material-ui/icons/Delete';
import ChevronLeftIcon from '#material-ui/icons/ChevronLeft';
import ChevronRightIcon from '#material-ui/icons/ChevronRight';
import ListItem from '#material-ui/core/ListItem';
import ListItemIcon from '#material-ui/core/ListItemIcon';
import ListItemText from '#material-ui/core/ListItemText';
import InboxIcon from '#material-ui/icons/MoveToInbox';
import MailIcon from '#material-ui/icons/Mail';
import Button from '#material-ui/core/Button';
import Menu from '#material-ui/core/Menu';
import MenuItem from '#material-ui/core/MenuItem';
import InfoIcon from '#material-ui/icons/Info';
import About from '../About/About';
// import { Link } from "react-router-dom";
import { useHistory } from "react-router-dom";
import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';
const drawerWidth = 240;
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
},
link: {
textDecoration: 'none',
color: theme.palette.text.primary
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
menuButton: {
marginRight: 36,
},
hide: {
display: 'none',
},
drawer: {
width: drawerWidth,
flexShrink: 0,
whiteSpace: 'nowrap',
},
drawerOpen: {
width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
drawerClose: {
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
overflowX: 'hidden',
width: theme.spacing(7) + 1,
[theme.breakpoints.up('sm')]: {
width: theme.spacing(9) + 1,
},
},
toolbar: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
},
content: {
flexGrow: 1,
padding: theme.spacing(3),
},
}));
export default function Sidebar() {
const classes = useStyles();
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const [component, setComponent] = React.useState('user')
const [anchorEl, setAnchorEl] = React.useState(null);
const history = useHistory();
const handleDrawerOpen = () => {
setOpen(true);
};
const handleDrawerClose = () => {
setOpen(false);
};
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
// <Router>
<div className={classes.root}>
<AppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: open,
})}
>
<Toolbar>
<h1>SGGB</h1>
<div className="alignment">
<Button aria-controls="simple-menu" aria-haspopup="true" onClick={handleClick}>
<h4>Menu</h4>
</Button>
<Menu
id="simple-menu"
anchorEl={anchorEl}
keepMounted
open={Boolean(anchorEl)}
onClose={handleClose}
>
<MenuItem onClick={handleClose}>Profile</MenuItem>
<MenuItem onClick={handleClose}>My account</MenuItem>
<MenuItem onClick={handleClose}>Logout</MenuItem>
</Menu>
</div>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
className={clsx(classes.drawer, {
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
})}
classes={{
paper: clsx({
[classes.drawerOpen]: open,
[classes.drawerClose]: !open,
}),
}}
>
<List>
<ListItem>
<IconButton
className={clsx(classes.menuButton, {
[classes.hide]: !open,
})}
onClick={handleDrawerClose}>
{theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />}
</IconButton>
</ListItem>
<ListItem>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerOpen}
edge="start"
className={clsx(classes.menuButton, {
[classes.hide]: open,
})}
>
<MenuIcon />
</IconButton>
</ListItem>
<Link to="/about" className={classes.link}>
<ListItem button key="about" >
<ListItemIcon>{<InfoIcon />}</ListItemIcon>
<ListItemText primary="About" />
</ListItem>
</Link>
</List>
</Drawer>
</div >
// </Router>
);
}
I have also referred to this post;
React Router display one component for all routes ( a header)
You have to put the Route component inside a Switch component like this :
<Router>
<div>
<Sidebar></Sidebar>
<Switch>
<Route exact path={"/"} component={Charts} />
<Route exact path={"/about"} component={About} />
</Switch>
<Footer></Footer>
</div>
</Router>
my build is not working correctly in build when i deploy to heroku. i have read about reordering the css but how do i verify this or make it work with material ui.
i have tried to look at the inspector and verify css is reordered.
this is the container and the whole screen and is being set off a good bit. the whole build in total has extra padding and the header is not working correctly. it can hopefully be seen at this address.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import classNames from 'classnames';
import { logoutUser } from '../../actions/authActions';
import { getSongs, getSong } from '../../actions/songActions';
import { clearCurrentProfile, getCurrentProfile } from '../../actions/profileActions';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import CssBaseline from '#material-ui/core/CssBaseline';
import Drawer from '#material-ui/core/Drawer';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import List from '#material-ui/core/List';
import Typography from '#material-ui/core/Typography';
import Divider from '#material-ui/core/Divider';
import IconButton from '#material-ui/core/IconButton';
import MenuIcon from '#material-ui/icons/Menu';
import ExpandMoreIcon from '#material-ui/icons/ExpandMore';
import ChevronLeftIcon from '#material-ui/icons/ChevronLeft';
import FadeIn from 'react-fade-in';
import ListItem from '#material-ui/core/ListItem';
import Modal from '#material-ui/core/Modal';
import Editor from "./Editor";
import Viewer from "./Viewer";
import ANContainer from '../audio-and-notes/ANContainer';
import AddSongModal from './AddSongModal';
import Resources from '../resources/Resources';
import Songs from '../songs/Songs';
import Song from '../song/Song';
import Spinner from '../../common/Spinner';
import { MenuItem } from '#material-ui/core';
import InboxIcon from "#material-ui/icons/MoveToInbox";
import ListItemText from "#material-ui/core/ListItemText";
import Menu from "#material-ui/core/Menu";
import MailIcon from "#material-ui/icons/Mail";
import { ExpansionPanelDetails } from "#material-ui/core";
const logo = require('../../img/songbird-logo.png');
const drawerWidth = 276;
const styles = theme => ({
root: {
display: 'flex',
},
toolbar: {
paddingRight: 24, // keep right padding when drawer closed
},
toolbarIcon: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: '0 8px',
...theme.mixins.toolbar,
},
appBar: {
backgroundColor: "#203e55",
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
appBarShift: {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
menuButton: {
marginLeft: 12,
marginRight: 36,
},
menuButtonHidden: {
display: 'none',
},
//right side menu
menu2Button: {
marginLeft: 0,
marginRight: 0,
},
menu2ButtonHidden: {
display: 'none',
},
//songbook
drawerTitle: {
color: "white",
flexGrow: 1,
textAlign: "center"
},
//songbird
title: {
marginLeft: "300px",
flexGrow: 1,
fontFamily: 'Open Sans, sans-serif'
},
drawerPaper: {
backgroundColor: "#203e55",
color: "white",
position: 'relative',
whiteSpace: 'nowrap',
width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
},
drawerPaperClose: {
overflowX: 'hidden',
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
//how much it pops out from the drawer pre-view
width: theme.spacing.unit * 0,
[theme.breakpoints.up('sm')]: {
width: theme.spacing.unit * 0,
},
},
appBarSpacer: theme.mixins.toolbar,
content: {
flexGrow: 1,
padding: theme.spacing.unit * 3,
height: '96.6vh',
overflow: 'auto',
},
h5: {
marginBottom: theme.spacing.unit * 2,
},
});
const options = ["Viewer", "Resources", "Notes"];
class AppContainer extends Component {
state = {
open: false,
left: false,
right: false,
anchorEl: null,
selectedIndex: 0
};
toggleDrawer = (side, open) => () => {
this.setState({ [side]: open
});
};
componentDidMount(){
this.props.getSongs();
this.props.getCurrentProfile();
}
//trying to maintain the component state for switcher
pageControl() {
if (this.state.selectedIndex === 0) {
return <Viewer />;
} else if (this.state.selectedIndex === 1) {
return <Resources />;
} else if (this.state.selectedIndex === 2) {
return <ANContainer />;
}
}
toggleDrawer = (side, open) => () => {
this.setState({
[side]: open,
});
};
handleDrawerOpen = () => {
this.setState({ open: true });
};
handleDrawerClose = () => {
this.setState({ open: false });
};
handleDrawerOpen = () => {
this.setState({ open: true });
};
handleDrawerClose = () => {
this.setState({ open: false });
};
handleClickListItem = event => {
this.setState({ anchorEl: event.currentTarget });
this.pageControl();
};
handleMenuItemClick = (event, index) => {
this.setState({ selectedIndex: index, anchorEl: null });
};
handleClose = () => {
this.setState({ anchorEl: null });
};
openSongModal = () => {
//open popup here
}
onLogoutClick(e){
e.preventDefault();
this.props.clearCurrentProfile();
this.props.logoutUser();
}
render(){
//for routing
const { isAuthenticated, user } = this.props.auth;
const { profile, loading } = this.props.profile;
const { classes } = this.props;
const { anchorEl } = this.state;
//will display iframe for wix site if the user does not have an account
const unauthContent = (
<div>
<nav class="navbar">
<div class="nav-wrapper">
<Link to="/" class="brand-logo"><img className="navlogo" src={logo} /></Link>
<ul class="right hide-on-med-and-down">
<li><Link to="/register">Sign Up</Link></li>
<li><Link to="/login">Log In</Link></li>
</ul>
</div>
</nav>
<iframe
style={{height: "92vh", width: "100%"}}
src="https://www.songbirdapp.com/"
frameBorder="none">
</iframe>
</div>
);
//rendered content
return(
<div className={classes.root}>
<CssBaseline />
{/* NAVBAR SECTION!!! */}
<AppBar
position="absolute"
className={classNames(classes.appBar, this.state.open && classes.appBarShift)}
>
<Toolbar disableGutters={!this.state.open} className={classes.toolbar}>
<IconButton
color="inherit"
aria-label="Open drawer"
onClick={this.handleDrawerOpen}
className={classNames(
classes.menuButton,
this.state.open && classes.menuButtonHidden,
)}
>
<MenuIcon />
</IconButton>
<Typography
component="h1"
variant="h6"
color="inherit"
noWrap
className={classes.title}
>
Editor
</Typography>
<div className="hide-on-med-and-down">
</div>
{/* TO CHANGE THE VIEWER RESOURCE PANEL */}
<List
component="nav-wrapper"
style={{
display: "flex",
flexDirection: "row",
alignContent: "center",
justifyContent: "flex-end",
width: "14%",
backgroundColor: "transparent"
}}
>
<ListItem
button
aria-haspopup="true"
aria-controls="lock-menu"
aria-label="Select Resource"
onClick={this.handleClickListItem}
>
<ListItemText
style={{
color: "white"
}}
primary={options[this.state.selectedIndex]}
/>
<ExpandMoreIcon />
</ListItem>
</List>
<Menu
id="lock-menu"
anchorEl={anchorEl}
open={Boolean(anchorEl)}
onClose={this.handleClose}
>
{options.map((option, index) => (
<MenuItem
key={option}
disabled={index === 4}
selected={index === this.state.selectedIndex}
onClick={event =>
this.handleMenuItemClick(event, index) & this.pageControl()
}
>
{option}
</MenuItem>
))}
</Menu>
{/* End Resources */}
</Toolbar>
</AppBar>
{/* NAVBAR SECTION END */}
{/* LEFT DRAWER */}
<Drawer
variant="permanent"
classes={{
paper: classNames(classes.drawerPaper, !this.state.open && classes.drawerPaperClose),
}}
open={this.state.open}
>
<div className={classes.toolbarIcon}>
<Typography variant="h6" className={classes.drawerTitle}>
Songs
</Typography>
<IconButton onClick={this.handleDrawerClose}>
<ChevronLeftIcon style={{color: "white"}}/>
</IconButton>
</div>
<Divider />
<List>
<AddSongModal />
<Songs />
</List>
<Divider />
<List>
<ListItem>
<Link className="menu-listitem" to="/myprofile">
{user.firstName} {user.lastName}
</Link>
</ListItem>
<ListItem>
<Link className="menu-listitem" to="/subscription">
Your Subscription
</Link>
</ListItem>
<ListItem>
<a className="logout-listitem"
href=""
onClick={this.onLogoutClick.bind(this)}
>
Logout</a>
</ListItem>
</List>
</Drawer>
{/* LEFT DRAWER END */}
<main className={classes.content}>
<div
className="row no-padding"
style={{
display: "flex",
margin: 0
}}
>
<div
className="col s12 no-padding"
style={{
margin: 0
}}
>
<Song />
</div>
<div className="col s12 m9 no-padding" style={{}}>
{this.pageControl()}
</div>
</div>
</main>
{/* RIGHT DRAWER TO BE USED FOR DRAFTS */}
{/* <Drawer
anchor="right"
variant="permanent"
classes={{
paper: classNames(classes.drawerPaper, !this.state.open && classes.drawerPaperClose),
}}
open={this.state.open}
>
<div className={classes.toolbarIcon}>
<Typography variant="h6" className={classes.drawerTitle}>
Songs
</Typography>
<IconButton onClick={this.handleDrawerTwoClose}>
<ChevronLeftIcon />
</IconButton>
</div>
<List>
<ListItem>Draft 04/12/2019 1PM</ListItem>
<ListItem>Draft 04/12/2019 12:30PM</ListItem>
<ListItem>Draft 04/10/2019 3PM</ListItem>
<ListItem>Draft 04/09/2019 11AM</ListItem>
<ListItem>Draft 04/09/2019 9PM</ListItem>
<ListItem>Draft 04/08/2019 8:34PM</ListItem>
</List>
</Drawer> */}
{/* RIGHT DRAWER END */}
</div>
);
}
}
AppContainer.propTypes = {
getCurrentProfile: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
profile: PropTypes.object.isRequired,
song: PropTypes.object.isRequired,
classes: PropTypes.object.isRequired,
logoutUser: PropTypes.func.isRequired,
getSongs: PropTypes.func.isRequired,
};
const mapStateToProps = (state) => ({
profile: state.profile,
auth: state.auth,
song: state.song,
});
export default connect(mapStateToProps, { logoutUser, getCurrentProfile, clearCurrentProfile, getSongs, getSong })(withStyles(styles)(AppContainer));
https://ovrchr-songbirdapp.herokuapp.com/
How to active side menu in react application. I am using ListItem for display side menu in my application. But in side menu when I click on ListItem then it will redirect to new page. So How can I selected or active side menu. I tried to active using state but page is redirect to another page. So state will not work.
//import React from "react";
import React, { Component, Fragment } from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
import { withStyles } from "#material-ui/core/styles";
import Drawer from "#material-ui/core/Drawer";
import AppBar from "#material-ui/core/AppBar";
import Toolbar from "#material-ui/core/Toolbar";
import List from "#material-ui/core/List";
import CssBaseline from "#material-ui/core/CssBaseline";
import Typography from "#material-ui/core/Typography";
import Divider from "#material-ui/core/Divider";
import IconButton from "#material-ui/core/IconButton";
import MenuIcon from "#material-ui/icons/Menu";
import ChevronLeftIcon from "#material-ui/icons/ChevronLeft";
import ChevronRightIcon from "#material-ui/icons/ChevronRight";
import ListItem from "#material-ui/core/ListItem";
import ListItemIcon from "#material-ui/core/ListItemIcon";
import ListItemText from "#material-ui/core/ListItemText";
import { Link } from "./Router";
import TimerIcon from "#material-ui/icons/Timer";
import AssignmentIcon from "#material-ui/icons/Assignment";
import ReportIcon from "#material-ui/icons/Report";
import TimelineIcon from "#material-ui/icons/Timeline";
import TodoIcon from "#material-ui/icons/PlayCircleFilledWhite";
const drawerWidth = 240;
const styles = theme => ({
root: {
display: "flex"
},
appBar: {
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(["width", "margin"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
})
},
appBarShift: {
marginLeft: drawerWidth,
width: `calc(100% - ${drawerWidth}px)`,
transition: theme.transitions.create(["width", "margin"], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
})
},
menuButton: {
marginLeft: 12,
marginRight: 36
},
hide: {
display: "none"
},
drawer: {
width: drawerWidth,
flexShrink: 0,
whiteSpace: "nowrap"
},
drawerOpen: {
width: drawerWidth,
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
})
},
drawerClose: {
transition: theme.transitions.create("width", {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
overflowX: "hidden",
width: theme.spacing.unit * 7 + 1,
[theme.breakpoints.up("sm")]: {
width: theme.spacing.unit * 9 + 1
}
},
toolbar: {
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
padding: "0 8px",
...theme.mixins.toolbar
},
content: {
flexGrow: 1,
padding: theme.spacing.unit * 3
}
});
class MiniDrawer extends React.Component {
state = {
open: false,
selectedIndex: 0
};
handleDrawerOpen = () => {
this.setState({ open: true });
};
handleDrawerClose = () => {
this.setState({ open: false });
};
render() {
const { classes, theme } = this.props;
return (
<Fragment>
<CssBaseline />
<AppBar
position="fixed"
className={classNames(classes.appBar, {
[classes.appBarShift]: this.state.open
})}
>
<Toolbar disableGutters={!this.state.open}>
<IconButton
color="inherit"
aria-label="Open drawer"
onClick={this.handleDrawerOpen}
className={classNames(classes.menuButton, {
[classes.hide]: this.state.open
})}
>
<MenuIcon />
</IconButton>
<Typography variant="h6" color="inherit" noWrap>
Initio Technologies
</Typography>
</Toolbar>
</AppBar>
<Drawer
variant="permanent"
className={classNames(classes.drawer, {
[classes.drawerOpen]: this.state.open,
[classes.drawerClose]: !this.state.open
})}
classes={{
paper: classNames({
[classes.drawerOpen]: this.state.open,
[classes.drawerClose]: !this.state.open
})
}}
open={this.state.open}
>
<div className={classes.toolbar}>
<IconButton onClick={this.handleDrawerClose}>
{theme.direction === "rtl" ? (
<ChevronRightIcon />
) : (
<ChevronLeftIcon />
)}
</IconButton>
</div>
<Divider />
<List>
<ListItem
button
key="Time Tracker"
component={Link}
to="/timetracker"
>
<ListItemIcon>
<TimerIcon />
</ListItemIcon>
<ListItemText primary="Time Tracker" />
</ListItem>
<ListItem
button
key="Project"
component={Link}
to="/project"
>
<ListItemIcon>
<AssignmentIcon />
</ListItemIcon>
<ListItemText primary="Project" />
</ListItem>
<ListItem button key="Kanban" component={Link} to="/kanban">
<ListItemIcon>
<TimelineIcon />
</ListItemIcon>
<ListItemText primary="Kanban" />
</ListItem>
<ListItem
button
key="Todo"
component={Link}
to="/todo"
>
<ListItemIcon>
<TodoIcon />
</ListItemIcon>
<ListItemText primary="Todo" />
</ListItem>
<ListItem button key="Reports" component={Link} to="/reports">
<ListItemIcon>
<ReportIcon />
</ListItemIcon>
<ListItemText primary="Reports" />
</ListItem>
</List>
<Divider />
</Drawer>
</Fragment>
);
}
}
MiniDrawer.propTypes = {
classes: PropTypes.object.isRequired,
theme: PropTypes.object.isRequired
};
export default withStyles(styles, { withTheme: true })(MiniDrawer);
Anyone please suggest me a solution.
Thanks
There are two ways to what I can think:
Have a Wrapper Component something like this:
const Wrapper = () => (
<React.Fragment>
<Sidebar />
<Content />
</React.Fragment>
)
In Content you can use route based rendering to switch the content. And thus manage state in sidebar.
Get the location of where your app is and setting the active item using this key.
You can use react-router to handle routing.
Hope this helps!