Material-Ui reordered css upon react build when deploying to heroku - reactjs

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/

Related

How can i set Routing while creating admin panel

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

converting material ui functional component Mini variant drawer to class component Reactjs

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>
);
}
}

How to active side menu in react js

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!

Drawer Content Change

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);

React PDF viewer component rerenders constantly

I am using a React PDF viewer in my project. I have a react mui dialog component that I use with react draggable to drag it around.
import React from "react";
import withStyles from "#material-ui/core/styles/withStyles";
import makeStyles from "#material-ui/core/styles/makeStyles";
import DialogContent from "#material-ui/core/DialogContent";
import IconButton from "#material-ui/core/IconButton";
import ClearIcon from "#material-ui/icons/Clear";
import Draggable from "react-draggable";
import Paper from "#material-ui/core/Paper";
import Dialog from "#material-ui/core/Dialog";
import PDFViewer from "./PDFViewer";
function PaperComponent({...props}) {
return (
<Draggable
>
<Paper {...props} />
</Draggable>
);
}
const StyledDialog = withStyles({
root: {
pointerEvents: "none"
},
paper: {
pointerEvents: "auto"
},
scrollPaper: {
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
marginRight: 20
}
})(props => <Dialog hideBackdrop {...props} />);
const useStyles = makeStyles({
dialog: {
cursor: 'move'
},
dialogContent: {
'&:first-child': {
padding: 10,
background: 'white'
}
},
clearIcon: {
position: 'absolute',
top: -20,
right: -20,
background: 'white',
zIndex: 1,
'&:hover': {
background: 'white'
}
},
paper: {
overflowY: 'visible',
maxWidth: 'none',
maxHeight: 'none',
width: 550,
height: 730
}
});
const PDFModal = (props) => {
const classes = useStyles();
const {open, onClose, pdfURL} = props;
return (
<StyledDialog
open={open}
classes={{root: classes.dialog, paper: classes.paper}}
PaperComponent={PaperComponent}
aria-labelledby="draggable-dialog"
>
<DialogContent classes={{root: classes.dialogContent}} id="draggable-dialog">
<IconButton className={classes.clearIcon} aria-label="Clear" onClick={onClose}>
<ClearIcon/>
</IconButton>
<PDFViewer
url={pdfURL}
/>
</DialogContent>
</StyledDialog>
);
};
export default PDFModal;
And this is the PDFViewer component:
import React from 'react';
import { Viewer, SpecialZoomLevel, Worker } from '#react-pdf-viewer/core';
import { defaultLayoutPlugin } from '#react-pdf-viewer/default-layout';
import '#react-pdf-viewer/core/lib/styles/index.css';
import '#react-pdf-viewer/default-layout/lib/styles/index.css';
import ArrowForward from "#material-ui/icons/ArrowForward";
import ArrowBack from "#material-ui/icons/ArrowBack";
import Button from "#material-ui/core/Button";
import IconButton from "#material-ui/core/IconButton";
import RemoveCircleOutlineIcon from '#material-ui/icons/RemoveCircleOutline';
import AddCircleOutlineIcon from '#material-ui/icons/AddCircleOutline';
import './PDFViewer.css';
const PDFViewer = ({url}) => {
const renderToolbar = (Toolbar) => (
<Toolbar>
{
(slots) => {
const {
CurrentPageLabel, CurrentScale, GoToNextPage, GoToPreviousPage, ZoomIn, ZoomOut,
} = slots;
return (
<div
style={{
alignItems: 'center',
display: 'flex',
}}
>
<div style={{ padding: '0px 2px' }}>
<ZoomOut>
{
(props) => (
<IconButton aria-label="delete" onClick={props.onClick}>
<RemoveCircleOutlineIcon />
</IconButton>
)
}
</ZoomOut>
</div>
<div style={{ padding: '0px 2px' }}>
<CurrentScale>
{
(props) => (
<span>{`${Math.round(props.scale * 100)}%`}</span>
)
}
</CurrentScale>
</div>
<div style={{ padding: '0px 2px' }}>
<ZoomIn>
{
(props) => (
<IconButton aria-label="delete" onClick={props.onClick}>
<AddCircleOutlineIcon />
</IconButton>
)
}
</ZoomIn>
</div>
<div style={{ padding: '0px 2px', marginLeft: 'auto' }}>
<GoToPreviousPage>
{
(props) => (
<Button
style={{
cursor: props.isDisabled ? 'not-allowed' : 'pointer',
height: '30px',
width: '30px'
}}
disabled={props.isDisabled}
disableElevation
disableFocusRipple
onClick={props.onClick}
variant="outlined">
<ArrowBack fontSize="small"/>
</Button>
)
}
</GoToPreviousPage>
</div>
<div style={{ padding: '0px 2px' }}>
<CurrentPageLabel>
{
(props) => (
<span>{`${props.currentPage + 1} av ${props.numberOfPages}`}</span>
)
}
</CurrentPageLabel>
</div>
<div style={{ padding: '0px 2px' }}>
<GoToNextPage>
{
(props) => (
<Button
style={{
cursor: props.isDisabled ? 'not-allowed' : 'pointer',
height: '30px',
width: '30px'
}}
disabled={props.isDisabled}
disableElevation
disableFocusRipple
onClick={props.onClick}
variant="outlined">
<ArrowForward fontSize="small"/>
</Button>
)
}
</GoToNextPage>
</div>
</div>
)
}
}
</Toolbar>
);
const defaultLayoutPluginInstance = defaultLayoutPlugin({
renderToolbar,
sidebarTabs: defaultTabs => [defaultTabs[1]]
});
// constantly called
console.log('entered')
return (
<div
style={{
height: '100%',
}}
>
<Worker workerUrl="https://unpkg.com/pdfjs-dist#2.5.207/build/pdf.worker.min.js">
<Viewer
fileUrl={url}
defaultScale={SpecialZoomLevel.PageFit}
plugins={[
defaultLayoutPluginInstance
]}
/>
</Worker>
</div>
);
};
export default PDFViewer;
I can see in the console that PDFViewer is being constantly called. I am not sure what is causing this rerenders the whole time?
Isn't it make sense to re-render when you have a new fileUrl passed to PDFModal? The following sequence should be how the app is executed.
PDFModal, PDFViewer and other related components init
When a file is dragged into the PaperComponent context, the upper level component handles it and passing pdfURL as props
const PDFModal = (props) => {
const { ......., pdfURL } = props;
//...skipped code
return (
<StyledDialog
PaperComponent={PaperComponent}
>
//...skipped code
<PDFViewer
url={pdfURL}
/>
</StyledDialog>
);
};
PDFViewer updated because there is a new prop.
const PDFViewer = ({ url }) => {
//...skipped code
return (
//...skipped code
<Viewer
fileUrl={url}
/>
);
}
I agree what #LindaPaiste said, putting Toolbar maybe an option since it doesn't use the url props passed in. For the re-render problem, I suggest that useCallback can be used to wrap the whole PDFViewer component. Only update the component when the url has changed.
This link provide some insights on when to use useCallback which can be a reference.
const PDFViewer = useCallback(
({ url }) => {
//...skipped code
return (
//...skipped code
<Viewer
fileUrl={url}
/>
)
}, [url])

Resources