@material-ui/core#Badge JavaScript Examples
The following examples show how to use
@material-ui/core#Badge.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: NationAvatar.js From dipact with GNU General Public License v3.0 | 6 votes |
badger(content) {
if (
this.props.gameState &&
(this.props.gameState.Properties.Muted || []).indexOf(
this.props.nation
) !== -1
) {
return this.buttoner(
<Badge
badgeContent={<MuteIcon />}
overlap="circle"
>
{content}
</Badge>
);
} else {
return this.buttoner(content);
}
}
Example #2
Source File: OftadehAvatarBadge.jsx From oftadeh-react-admin with MIT License | 6 votes |
StyledBadge = withStyles(theme => ({
badge: {
backgroundColor: "#44b700",
color: "#44b700",
boxShadow: `0 0 0 2px ${theme.palette.background.paper}`,
"&::after": {
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
borderRadius: "50%",
animation: "$ripple 1.2s infinite ease-in-out",
border: "1px solid currentColor",
content: '""'
}
},
"@keyframes ripple": {
"0%": {
transform: "scale(.8)",
opacity: 1
},
"100%": {
transform: "scale(2.4)",
opacity: 0
}
}
}))(Badge)
Example #3
Source File: Header.js From pwa with MIT License | 6 votes |
render() {
return (
<div className="HeaderWrapper" name="close" onClick={this.handleOpen}>
<div className="notif-button-wrapper">
<Badge variant="dot" color="primary">
<button type="button" name="open" onClick={this.handleOpen}>
<img
src={notification}
className="notif-btn"
alt="Notification"
/>
</button>
</Badge>
<div className="logo">
<img src={logo} alt="logo" />
</div>
<Typography variant="subtitle2" className="beta-version">
نسخه آزمایشی
</Typography>
</div>
<Dialog open={this.state.isDialogOpen}>
<Box ml={3} className="notif-msg">
این برنامه در حال به روز رسانی میباشد، برای بهرهمندی از جدیدترین
امکانات، بهروز باشید!
</Box>
</Dialog>
</div>
);
}
Example #4
Source File: NavigationFrame.js From spl-token-wallet with Apache License 2.0 | 6 votes |
function ConnectionsButton() {
const classes = useStyles();
const setPage = usePage()[1];
const onClick = () => setPage('connections');
const connectedWallets = useConnectedWallets();
const connectionAmount = Object.keys(connectedWallets).length;
return (
<>
<Hidden smUp>
<Tooltip title="Manage Connections">
<IconButton color="inherit" onClick={onClick}>
<Badge
badgeContent={connectionAmount}
classes={{ badge: classes.badge }}
>
<ConnectionIcon />
</Badge>
</IconButton>
</Tooltip>
</Hidden>
<Hidden xsDown>
<Badge
badgeContent={connectionAmount}
classes={{ badge: classes.badge }}
>
<Button color="inherit" onClick={onClick} className={classes.button}>
Connections
</Button>
</Badge>
</Hidden>
</>
);
}
Example #5
Source File: FilterButton.js From AED-Map with MIT License | 6 votes |
FilterButton = ({ isOpen, setIsOpen, filter }) => {
const tooltipMessage = isOpen
? 'Закрити фільтр'
: 'Відкрити фільтр';
const toggleFilter = () => {
setIsOpen(prevState => !prevState);
};
return (
<IconButton
color="primary"
aria-label="filter"
onClick={toggleFilter}
>
{filter ? (
<Badge color="secondary" variant="dot">
<Tooltip title={tooltipMessage}>
<FilterListIcon />
</Tooltip>
</Badge>
) : (
<Tooltip title={tooltipMessage}>
<FilterListIcon />
</Tooltip>
)}
</IconButton>
);
}
Example #6
Source File: TopBar.js From paper-and-ink with MIT License | 6 votes |
function Topbar(props) {
const { className, children, openSidebar, onToggleSidebar } = props;
const classes = useStyles(props);
const [notifications] = useState([{ message: 'A Message', status: 'success' }]);
return (
<AppBar className={clsx(classes.root, className)}>
<Toolbar className={classes.toolbar}>
<div className={classes.brandWrapper}>
<div className={classes.logo}>Paper & Ink</div>
<IconButton className={classes.menuButton} aria-label="Menu" onClick={onToggleSidebar}>
{openSidebar ? <CloseIcon /> : <MenuIcon />}
</IconButton>
</div>
<ThemeToggler className={classes.themeToggler} />
<IconButton className={classes.notificationsButton}>
<Badge badgeContent={notifications.length} color="primary" variant="dot">
<NotificationsIcon />
</Badge>
</IconButton>
<IconButton className={classes.signOutButton}>
<InputIcon />
</IconButton>
</Toolbar>
{children}
</AppBar>
);
}
Example #7
Source File: DevicesBadge.js From budgie-stream with MIT License | 6 votes |
DevicesBadge = () => {
const { playback } = useContext(ClientContext);
const [state] = playback;
const [nbrDevices, setNbrDevices] = useState("0");
// eslint-disable-next-line
const getNbrOfDevices = () => {
const count = state.devices.filter((device) => device.selected === true)
.length;
setNbrDevices(count);
};
useEffect(() => {
getNbrOfDevices();
}, [state.devices, getNbrOfDevices]);
return (
<>
<Tooltip title="Devices/Groups Selected" aria-label="Devices">
<Badge color="secondary" badgeContent={nbrDevices}>
<SpeakerIcon />
</Badge>
</Tooltip>
</>
);
}
Example #8
Source File: ProductCartWidget.js From course-manager with MIT License | 6 votes |
// ----------------------------------------------------------------------
export default function CartWidget() {
return (
<RootStyle>
<Badge showZero badgeContent={0} color="error" max={99}>
<Icon icon={shoppingCartFill} width={24} height={24} />
</Badge>
</RootStyle>
);
}
Example #9
Source File: VisualizerOptionSelectionGrid.js From Otto with MIT License | 6 votes |
StyledBadge = withStyles((theme) => ({
badge: {
width: 10,
"&::after": {
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
borderRadius: "50%",
content: '""',
},
},
}))(Badge)
Example #10
Source File: NavBar.js From inventory-management-web with MIT License | 5 votes |
NavBar = ({ mobileOpen, setMobileOpen, tabletOpen, setTabletOpen }) => {
// used to check current url
const location = useLocation();
const theme = useTheme();
// true if in tablet mode
const tablet = useMediaQuery(theme.breakpoints.only('sm'));
const mobile = useMediaQuery(theme.breakpoints.only('xs'));
const isLoggedIn = location.pathname !== '/login';
const classes = useStyles(isLoggedIn);
const { expiryListBadge } = useContext(ExpiryListContext);
// handle opening and closing of drawer
const handleDrawerToggle = () => {
if (tablet) {
setTabletOpen(!tabletOpen);
} else {
setMobileOpen(!mobileOpen);
}
};
return (
<div className={classes.root}>
<AppBar position='fixed'>
<Toolbar>
<Hidden mdUp>
<IconButton
edge='start'
className={classes.menuButton}
color='inherit'
onClick={handleDrawerToggle}
>
{tabletOpen ? (
<ChevronLeftIcon />
) : (
<Badge
badgeContent={expiryListBadge}
color='primary'
overlap='circle'
className={classes.tabBadge}
invisible={!mobile}
>
<MenuIcon />
</Badge>
)}
</IconButton>
</Hidden>
<Typography variant='h6' className={classes.title}>
Inventory Management Web App
</Typography>
<AlertDialog />
</Toolbar>
</AppBar>
</div>
);
}
Example #11
Source File: Topbar.js From telar-cli with MIT License | 5 votes |
Topbar = props => {
const { className, onSidebarOpen, ...rest } = props;
const classes = useStyles();
const [notifications] = useState([]);
return (
<AppBar
{...rest}
className={clsx(classes.root, className)}
>
<Toolbar>
<RouterLink to="/">
<h1 style={{color:'white'}}>Telar</h1>
</RouterLink>
<div className={classes.flexGrow} />
<Hidden mdDown>
<IconButton color="inherit">
<Badge
badgeContent={notifications.length}
color="primary"
variant="dot"
>
<NotificationsIcon />
</Badge>
</IconButton>
<IconButton
className={classes.signOutButton}
color="inherit"
>
<InputIcon />
</IconButton>
</Hidden>
<Hidden lgUp>
<IconButton
color="inherit"
onClick={onSidebarOpen}
>
<MenuIcon />
</IconButton>
</Hidden>
</Toolbar>
</AppBar>
);
}
Example #12
Source File: nav-filter-by-values.js From horondi_admin with MIT License | 5 votes |
NavFilterByValues = ({
filterByMultipleOptions: {
filters,
setFilterHandler,
label,
selectItems,
objForTranslateRenderItems
}
}) => {
const styles = useStyles();
const { optionHandler, setRenderValue } = useFilter(
selectItems,
setFilterHandler
);
return (
<div className={styles.formblock}>
<Badge
badgeContent={filters.length}
color={materialUiConstants.styleError}
anchorOrigin={badgePosition}
>
<FormControl style={{ minWidth: 170 }} className={styles.formControl}>
<InputLabel id={materialUiConstants.checkBoxLabel}>
{label}
</InputLabel>
<Select
labelId={materialUiConstants.checkBoxLabel}
id={materialUiConstants.checkBoxId}
multiple
value={filters}
onChange={optionHandler}
renderValue={(selected) =>
setRenderValue(selected, objForTranslateRenderItems)
}
input={<Input />}
autoWidth
MenuProps={MenuProps}
>
{selectItems.map((item) => (
<MenuItem key={item.key} value={item.key}>
<Checkbox checked={filters.indexOf(item.key) > -1} />
<ListItemText primary={item.value} />
</MenuItem>
))}
</Select>
</FormControl>
</Badge>
</div>
);
}
Example #13
Source File: options-picker.js From horondi_admin with MIT License | 5 votes |
OptionsPicker = ({ value, handler, label, options }) => {
const styles = useStyles();
const { optionHandler, setRenderValue } = useFilter(options, handler);
const filteredOptions = {};
options.map((option) =>
Object.assign(filteredOptions, { [option.value]: option.label })
);
return (
<Badge
badgeContent={value.length}
color={materialUiConstants.styleError}
anchorOrigin={badgePosition}
>
<FormControl className={styles.container}>
<InputLabel id={materialUiConstants.checkBoxLabel}>{label}</InputLabel>
<Select
labelId={materialUiConstants.checkBoxLabel}
id={materialUiConstants.checkBoxId}
multiple
value={value}
onChange={optionHandler}
renderValue={(selected) => setRenderValue(selected, filteredOptions)}
input={<Input />}
autoWidth
MenuProps={MenuProps}
>
{options.map((item) => (
<MenuItem key={item.value} value={item.value}>
<Checkbox checked={value.indexOf(item.value) > -1} />
<ListItemText primary={item.label} />
</MenuItem>
))}
</Select>
</FormControl>
</Badge>
);
}
Example #14
Source File: positions.jsx From GraphVega with MIT License | 5 votes |
Positions = props => {
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
const displayQuantity = index => {
return props.positions[index].position === "long" ? (
<div className="text-success">+{props.positions[index].quantity}</div>
) : (
<div className="text-danger">{props.positions[index].quantity}</div>
);
};
return (
<>
<Badge badgeContent={props.positions.length} color="secondary">
<Button onClick={handleShow} variant="contained" color="primary">
Positions
</Button>
</Badge>
<Modal
show={show}
onHide={handleClose}
style={{ background: "rgba(0, 0, 0,0.5)" }}
>
<Modal.Body>
<h4>
<b>Positions</b>
</h4>
<br />
{props.positions[0]?
""
:<div className="text-secondary">Looks like you have not added any positions yet! </div>
}
<Table>
{props.positions.map((option, index) => {
return (
<tr>
<th>
{displayQuantity(index)}
</th>
<th>
{option["description"]}
</th>
<th>
<Button
size="small"
// variant="outlined"
color="secondary"
onClick={() => {
props.onRemovePosition(index);
}}
>
<ClearIcon fontSize="small"/> Remove
</Button>
</th>
</tr>
);
})}
</Table>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={handleClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</>
);
}
Example #15
Source File: CardUrls.js From FireShort with MIT License | 5 votes |
export default function CardUrls(props) {
const history = useHistory();
const classes = useStyles();
return (
<Container className={classes.cardGrid} maxWidth="lg">
<Grid container spacing={4}>
{props.shortUrls.map((card) => (
<Grid item key={card.id} xs={12} sm={6} md={4}>
<Card className={classes.card}>
<CardHeader
action={
<Tooltip title={"Copy to clipboard"}>
<IconButton color="primary" className={classes.copyButton} onClick={() => { navigator.clipboard.writeText(window.location.origin + "/" + card.data.curl) }}>
<FileCopyOutlinedIcon />
</IconButton>
</Tooltip>
}
title={
<Tooltip title={card.data.track === true ? "Link Tracking ON" : "Link Tracking OFF"}>
<Badge color={card.data.track === true ? "primary" : "error"} variant="dot">
<Typography>{card.data.curl}</Typography>
</Badge>
</Tooltip>
}
titleTypographyProps={{
variant: "subtitle1"
}}
>
</CardHeader>
<CardContent className={classes.cardContent}>
<Box bgcolor="text.primary" color="background.paper" p={2} style={{ overflowX: 'auto', overflowY: 'hidden', whiteSpace: "nowrap" }}>
{card.data.lurl}
</Box>
</CardContent>
<CardActions className={classes.cardActions}>
<Tooltip title={"Preview link"}>
<IconButton size="small" color="primary" href={card.data.lurl} target="_blank">
<VisibilityIcon />
</IconButton>
</Tooltip>
<Tooltip title={"Edit link"}>
<IconButton size="small" onClick={() => props.handleEditShortUrl(card.data.curl)}>
<EditIcon />
</IconButton>
</Tooltip>
<Tooltip title={"Analytics"}>
<IconButton size="small" disabled={!card.data.track} onClick={() => history.push(`/analytics/${card.data.curl}`)}>
<AnalyticsIcon />
</IconButton>
</Tooltip>
<Tooltip title={"Delete link"}>
<IconButton size="small" color="secondary" onClick={() => props.handleDeleteShortUrl(card.data.curl)}>
<DeleteForeverIcon />
</IconButton>
</Tooltip>
<Tooltip title={card.data.hits + " Hits"}>
<IconButton onClick={() => { props.openHits(card.data.curl) }} style={{ cursor: "pointer" }}>
<Badge badgeContent={card.data.hits} color="secondary" max={Infinity} showZero>
<OpenInBrowser />
</Badge>
</IconButton>
</Tooltip>
<Tooltip title={"Password protect"}>
<IconButton size='small' color='default' onClick={() => props.toggleSecurity(card.data.curl)}>
{card.data.locked ? <LockIcon /> : <LockOpenIcon />}
</IconButton>
</Tooltip>
</CardActions>
</Card>
</Grid>
))}
</Grid>
</Container>
);
}
Example #16
Source File: ChatMenu.js From dipact with GNU General Public License v3.0 | 4 votes |
render() {
return (
<div
style={{
position: "relative",
height: "100%",
}}
>
<Slide
direction="up"
in={!!this.state.activeChannel}
mountOnEnter
unmountOnExit
>
<div
style={{
top: 0,
left: 0,
bottom: 0,
right: 0,
background: "#ffffff",
position: "absolute",
zIndex: 1200,
}}
>
<ChatChannel
onNewGameState={this.props.onNewGameState}
gameState={this.props.gameState}
game={this.props.game}
phases={this.props.phases}
isActive={this.props.isActive}
createMessageLink={this.state.createMessageLink}
channel={this.state.activeChannel}
close={this.closeChannel}
loaded={(_) => {
this.loadChannels(true);
}}
parent={this}
/>
</div>
</Slide>
{this.state.channels && this.state.channels.length > 0 ? (
""
) : (
<Typography>No chat channels currently.</Typography>
)}
<ButtonGroup
orientation="vertical"
style={{
width: "100%",
height: "100%",
transform: "translateZ(0)",
WebkitTransform: "translateZ(0)",
overflowY: !!this.state.activeChannel
? "hidden"
: "scroll",
}}
>
{this.state.channels.map((channel) => {
return (
<Button
style={{
width: "100%",
justifyContent: "left",
paddingTop: "12px",
paddingBottom: "12px",
border: "none",
borderBottom: "1px solid rgb(40,26,26,0.1)",
borderRadius: "0px",
}}
onClick={(_) => {
this.openChannel(channel);
}}
key={channel.Properties.Members.join(",")}
>
{this.member &&
channel.Properties.NMessagesSince &&
channel.Properties.NMessagesSince.NMessages >
0 ? (
<Badge
badgeContent={
channel.Properties.NMessagesSince
.NMessages
}
overlap="circle"
color="primary"
>
{this.variant.Properties.Nations
.length ===
channel.Properties.Members.length ? (
<NationAvatarGroup
game={this.props.game}
newGameState={
this.props.newGameState
}
gameState={this.props.gameState}
variant={this.variant}
nations={
channel.Properties.Members
}
/>
) : (
<NationAvatarGroup
game={this.props.game}
newGameState={
this.props.newGameState
}
gameState={this.props.gameState}
variant={this.variant}
nations={channel.Properties.Members.filter(
(n) => {
return (
!this.member ||
n !==
this.member
.Nation
);
}
)}
/>
)}
</Badge>
) : this.variant.Properties.Nations.length ===
channel.Properties.Members.length ? (
<NationAvatarGroup
game={this.props.game}
newGameState={this.props.newGameState}
gameState={this.props.gameState}
variant={this.variant}
nations={channel.Properties.Members}
/>
) : (
<NationAvatarGroup
game={this.props.game}
newGameState={this.props.newGameState}
gameState={this.props.gameState}
variant={this.variant}
nations={channel.Properties.Members.filter(
(n) => {
return (
!this.member ||
n !== this.member.Nation
);
}
)}
/>
)}
{channel.Properties.NMessages &&
channel.Properties.LatestMessage ? (
<div
style={{
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
marginLeft: "8px",
minWidth: "0",
}}
>
<Typography
variant="body1"
style={{
textTransform: "none",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
width: "100%",
textAlign: "left",
}}
>
{channel.Properties.Members
.length ===
this.variant.Properties.Nations
.length
? "Everyone"
: channel.Properties.Members.filter(
(n) => {
return (
!this.member ||
n !==
this.member
.Nation
);
}
).map((n, i) => {
if (i === 0) {
return n;
} else {
return ", " + n;
}
})}{" "}
({channel.Properties.NMessages})
</Typography>
<Typography
variant="body2"
style={{
textTransform: "none",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "nowrap",
width: "100%",
textAlign: "left",
}}
>
{this.member ? (
this.member.Nation ===
channel.Properties.LatestMessage
.Sender ? (
<span
style={{
fontStyle: "italic",
}}
>
You:{" "}
</span>
) : channel.Properties.Members
.length > 2 ? (
channel.Properties
.LatestMessage.Sender +
": "
) : (
""
)
) : (
channel.Properties.LatestMessage
.Sender + ": "
)}
{
channel.Properties.LatestMessage
.Body
}
</Typography>
</div>
) : (
""
)}
</Button>
);
})}
</ButtonGroup>
{this.state.createMessageLink ? (
<React.Fragment>
<Fab
style={{
margin: "0px",
top: "auto",
right: "20px",
bottom: "20px",
left: "auto",
position: "fixed",
display: !!this.state.activeChannel
? "none"
: "flex",
}}
color="secondary"
aria-label="edit"
onClick={(_) => {
this.createChannelDialog.setState({
open: true,
});
}}
>
<CreateMessageIcon />
</Fab>
<CreateChannelDialog
game={this.props.game}
createChannel={(channel) => {
const newChannels = this.state.channels;
const oldChannel = newChannels.find((ch) => {
return helpers.deepEqual(
channel.Properties.Members,
ch.Properties.Members
);
});
if (!oldChannel) {
newChannels.push(channel);
}
const channelToUse = oldChannel || channel;
this.setState(
{
channels: newChannels,
},
(_) => {
gtag("event", "create_chat_channel");
this.openChannel(channelToUse);
}
);
}}
parentCB={(c) => {
this.createChannelDialog = c;
}}
/>
</React.Fragment>
) : (
""
)}
</div>
);
}
Example #17
Source File: Game.js From dipact with GNU General Public License v3.0 | 4 votes |
render() {
if (this.state.game) {
return (
<React.Fragment>
<AppBar
key="app-bar"
position="fixed"
color={this.state.laboratoryMode ? "secondary" : "primary"}
>
<Toolbar>
{!this.state.laboratoryMode ? (
<IconButton
onClick={this.props.close}
key="close"
edge="start"
color="secondary"
>
<CloseIcon />
</IconButton>
) : (
<IconButton
onClick={(_) => {
this.setState(
{
moreMenuAnchorEl: null,
laboratoryMode: !this.state.laboratoryMode,
},
(_) => {
if (!this.state.laboratoryMode) {
this.loadGame();
} else {
gtag("event", "enable_lab_mode");
}
}
);
}}
key="close"
edge="start"
color="primary"
>
<CloseIcon />
</IconButton>
)}
{!this.state.laboratoryMode &&
this.state.activePhase &&
this.state.activePhase.Properties.PhaseOrdinal > 1 ? (
<IconButton
onClick={this.phaseJumper(-1)}
key="previous"
edge="start"
color="secondary"
>
<PreviousIcon />
</IconButton>
) : !this.state.laboratoryMode ? (
<Box key="prev-spacer"></Box>
) : (
""
)}
{this.state.laboratoryMode ? (
<Typography variant="h6" style={{ marginRight: "8px" }}>
Sandbox
</Typography>
) : (
""
)}
{this.state.activePhase ? (
<Select
/* TODO: This might be a stretch, but Laboratory mode has SOME "real" and some "fake" turns. E.g. in spring 1902 I can move back to Spring 1901 and create an "alternative" 1901 and commit that.
Is it possible to make all the "hypothetical" phases to change color? Maybe let me know in the Discord chat and we can discuss more. */
/*
* Yes it is - 'real' phases have .Properties.ID, while fake phases don't (IIRC).
*/
style={
this.state.laboratoryMode
? {
width: "100%",
minWidth: "0",
borderBottom: "1px solid rgba(253, 226, 181, 0.7)",
color: "rgb(40, 26, 26)",
}
: {
width: "100%",
minWidth: "0",
borderBottom: "1px solid rgba(253, 226, 181, 0.7)",
color: "#FDE2B5",
}
}
key="phase-select"
value={this.state.activePhase.Properties.PhaseOrdinal}
onChange={this.changePhase}
label={helpers.phaseName(this.state.activePhase)}
>
{this.state.phases.map((phase) => {
return (
<MenuItem
key={phase.Properties.PhaseOrdinal}
style={{
textOverflow: "ellipsis",
}}
value={phase.Properties.PhaseOrdinal}
>
{helpers.phaseName(phase)}
{!this.state.game.Properties.Started ||
phase.Properties.Resolved ? (
""
) : (
<span
dataat={
new Date().getTime() +
phase.Properties.NextDeadlineIn * 1e-6
}
style={{
position: "relative",
top: "-6px",
fontSize: "xx-small",
left: "-5px",
zIndex: "1",
backgroundColor: "red",
borderRadius: "7px",
padding: "0 2px 1px 2px",
}}
>
{helpers.minutesToDuration(
(phase.Properties.NextDeadlineIn * 1e-9) / 60.0,
true
)}
</span>
)}
</MenuItem>
);
})}
</Select>
) : !this.state.laboratoryMode ? (
<Box key="curr-spacer" width="100%"></Box>
) : (
""
)}
{this.state.activePhase &&
this.state.activePhase.Properties.PhaseOrdinal <
this.state.phases[this.state.phases.length - 1].Properties
.PhaseOrdinal ? (
<IconButton
onClick={this.phaseJumper(1)}
edge="end"
key="next"
color="secondary"
>
<NextIcon />
</IconButton>
) : !this.state.laboratoryMode ? (
<Box key="next-spacer"></Box>
) : (
""
)}
{!this.state.laboratoryMode ? (
<IconButton
edge="end"
key="more-icon"
color="secondary"
onClick={(ev) => {
this.setState({
moreMenuAnchorEl: ev.currentTarget,
});
}}
>
<SettingsIcon />
</IconButton>
) : (
""
)}
<Menu
anchorEl={this.state.moreMenuAnchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
onClose={(_) => {
this.setState({ moreMenuAnchorEl: null });
}}
open={!!this.state.moreMenuAnchorEl}
>
<MenuItem
key="game-metadata"
onClick={(_) => {
this.setState({
moreMenuAnchorEl: null,
});
if (this.state.game.Properties.Started) {
this.gamePlayersDialog.setState({
open: true,
});
} else {
this.metadataDialog.setState({
open: true,
});
}
}}
>
Game & player info
</MenuItem>
{this.state.game.Properties.Started
? [
<MenuItem
key="scores"
onClick={(_) => {
this.setState({
moreMenuAnchorEl: null,
});
this.preliminaryScores.setState({
open: true,
});
}}
>
Scores
</MenuItem>,
this.state.game.Properties.Finished ? (
<MenuItem
key="results"
onClick={(_) => {
this.setState({
moreMenuAnchorEl: null,
});
this.gameResults.setState({
open: true,
});
}}
>
Results
</MenuItem>
) : (
""
),
]
: ""}
<Divider />
<MenuItem key="game-id" onClick={this.shareNative}>
{this.state.game.Properties.Started
? "Share game"
: "Invite players"}
</MenuItem>
<MenuItem
key="download-map"
onClick={(_) => {
this.setState({
moreMenuAnchorEl: null,
});
this.dip_map.downloadMap();
gtag("event", "download_map");
}}
>
Download map
</MenuItem>
<MenuItem
key="laboratory-mode"
onClick={(_) => {
this.setState(
{
moreMenuAnchorEl: null,
laboratoryMode: !this.state.laboratoryMode,
},
(_) => {
if (!this.state.laboratoryMode) {
this.loadGame();
} else {
gtag("event", "enable_lab_mode");
}
}
);
}}
>
{this.state.laboratoryMode
? "Turn off sandbox mode"
: "Sandbox mode"}
</MenuItem>
<Divider />
<MenuItem
key="How to play"
onClick={(_) => {
window.open(
"https://diplicity.notion.site/How-to-play-39fbc4d1f1924c928c3953095062a983",
"_blank"
);
}}
>
How to play
</MenuItem>
<MenuItem
key="debug-data"
onClick={(_) => {
helpers
.copyToClipboard(JSON.stringify(this.debugCounters))
.then((_) => {
this.setState({
moreMenuAnchorEl: null,
});
helpers.snackbar("Debug data copied to clipboard");
});
}}
>
Debug
</MenuItem>
</Menu>
{this.state.laboratoryMode ? (
<React.Fragment>
<IconButton
onClick={(_) => {
this.dip_map.downloadMap();
gtag("event", "download_map");
}}
color="primary"
edge="end"
style={{ marginLeft: "auto" }}
>
<DownloadIcon />
</IconButton>
<IconButton
onClick={(_) => {
this.dip_map.labShare();
}}
color="primary"
edge="end"
style={{ marginLeft: "auto" }}
>
<ShareIcon />
</IconButton>
</React.Fragment>
) : (
""
)}
</Toolbar>
{!this.state.laboratoryMode ? (
<React.Fragment>
{!this.state.game.Properties.Started ||
this.state.game.Links.find((l) => {
return l.Rel === "join";
}) ? (
<Toolbar
style={{
display: "flex",
justifyContent: "space-between",
minHeight: "53px",
}}
>
<div>
{this.state.game.Links.find((l) => {
return l.Rel === "join";
}) ? (
<Button
variant="outlined"
color="secondary"
key="join"
onClick={this.join}
>
Join
</Button>
) : (
""
)}
{this.state.game.Links.find((l) => {
return l.Rel === "leave";
}) ? (
<Button
variant="outlined"
color="secondary"
key="leave"
onClick={this.leave}
>
Leave
</Button>
) : (
""
)}
</div>
<div
style={{
display: "flex",
alignItems: "center",
}}
>
<NumMembersIcon />{" "}
<Typography
//TODO: Change this to not NMembers but Nmembers - replaceable.
variant="body2"
style={{ paddingLeft: "2px" }}
>
{this.state.game.Properties.NMembers}/
{this.state.variant.Properties.Nations.length}{" "}
</Typography>
</div>
</Toolbar>
) : (
""
)}
<Tabs
key="tabs"
value={this.state.activeTab}
onChange={this.changeTab}
display="flex"
variant="fullWidth"
>
<Tab value="map" icon={<MapIcon />} />
<Tab
value="chat"
icon={
this.state.member && this.state.unreadMessages > 0 ? (
<Badge badgeContent={this.state.unreadMessages}>
<ChatIcon />
</Badge>
) : (
<ChatIcon />
)
}
/>
{this.state.game.Properties.Started ? (
this.state.member &&
!this.state.activePhase.Properties.Resolved ? (
this.state.member.NewestPhaseState.OnProbation ||
!this.state.member.NewestPhaseState.ReadyToResolve ? (
<Tab
value="orders"
icon={
<SvgIcon>
<path
d="M9,0 C10.3,0 11.4,0.84 11.82,2 L11.82,2 L16,2 C17.1045695,2 18,2.8954305 18,4 L18,4 L18,18 C18,19.1045695 17.1045695,20 16,20 L16,20 L2,20 C0.8954305,20 0,19.1045695 0,18 L0,18 L0,4 C0,2.8954305 0.8954305,2 2,2 L2,2 L6.18,2 C6.6,0.84 7.7,0 9,0 Z M5,14 L3,14 L3,16 L5,16 L5,14 Z M15,14 L7,14 L7,16 L15,16 L15,14 Z M5,6 L3,6 L3,12 L5,12 L5,6 Z M15,10 L7,10 L7,12 L15,12 L15,10 Z M15,6 L7,6 L7,8 L15,8 L15,6 Z M9,2 C8.44771525,2 8,2.44771525 8,3 C8,3.55228475 8.44771525,4 9,4 C9.55228475,4 10,3.55228475 10,3 C10,2.44771525 9.55228475,2 9,2 Z"
id="order_open"
></path>
</SvgIcon>
}
/>
) : (
<Tab
value="orders"
icon={
<SvgIcon>
<path
d="M9,0 C10.3,0 11.4,0.84 11.82,2 L11.82,2 L16,2 C17.1045695,2 18,2.8954305 18,4 L18,4 L18,18 C18,19.1045695 17.1045695,20 16,20 L16,20 L2,20 C0.8954305,20 0,19.1045695 0,18 L0,18 L0,4 C0,2.8954305 0.8954305,2 2,2 L2,2 L6.18,2 C6.6,0.84 7.7,0 9,0 Z M13.4347826,7 L7.70608696,12.7391304 L4.56521739,9.60869565 L3,11.173913 L7.70608696,15.8695652 L15,8.56521739 L13.4347826,7 Z M9,2 C8.44771525,2 8,2.44771525 8,3 C8,3.55228475 8.44771525,4 9,4 C9.55228475,4 10,3.55228475 10,3 C10,2.44771525 9.55228475,2 9,2 Z"
id="order_confirmed"
></path>
</SvgIcon>
}
/>
)
) : (
<Tab value="orders" icon={<EventIcon />} />
)
) : (
""
)}
</Tabs>
</React.Fragment>
) : (
<Toolbar>
<Typography variant="body1" style={{ marginRight: "8px" }}>
Edit
</Typography>
<FormControlLabel
key="edit-mode"
control={
<Switch
onChange={(ev) => {
this.setState({
labEditMode: !ev.target.checked,
});
this.dip_map.setState({
labEditMode: !ev.target.checked,
});
}}
color="primary"
checked={!this.state.labEditMode}
/>
}
label="Play as"
/>
{!this.state.labEditMode ? (
<FormControl
key="play-as"
style={{
flexGrow: 1,
}}
>
<Select
value={this.state.labPlayAs}
onChange={(ev) => {
this.setState({
labPlayAs: ev.target.value,
});
this.dip_map.setState({
labPlayAs: ev.target.value,
});
}}
style={{
width: "100%",
minWidth: "0",
borderBottom: "1px solid rgba(253, 226, 181, 0.7)",
color: "rgb(40, 26, 26)",
}}
>
{this.state.variant.Properties.Nations.map((nation) => {
return (
<MenuItem key={nation} value={nation}>
{nation}
</MenuItem>
);
})}
</Select>
</FormControl>
) : (
""
)}
<IconButton
edge="end"
onClick={(ev) => {
this.dip_map.labResolve();
}}
style={{
marginLeft: "auto",
color: "rgb(40, 26, 26)",
}}
>
<FastForwardIcon />
</IconButton>
</Toolbar>
)}
</AppBar>
<div
key="map-container"
style={
this.state.laboratoryMode
? {
marginTop: "" + this.state.marginTop + "px",
height: "calc(100% - " + this.state.marginTop + "px)",
backgroundColor: "black",
display: this.state.activeTab === "map" ? "block" : "none",
}
: {
marginTop: "" + this.state.marginTop + "px",
height: "calc(100% - " + this.state.marginTop + "px)",
backgroundColor: "black",
display: this.state.activeTab === "map" ? "block" : "none",
}
}
>
<DipMap
parentCB={(c) => {
this.dip_map = c;
}}
onLeaveProbation={(_) => {
this.loadGame();
}}
debugCount={this.debugCount}
labPhaseResolve={this.labPhaseResolve}
serializePhaseState={this.serializePhaseState}
laboratoryMode={this.state.laboratoryMode}
isActive={this.state.activeTab === "map"}
game={this.state.game}
phase={this.state.activePhase}
corroborateSubscriber={this.receiveCorroboration}
variant={this.state.variant}
/>
</div>
<React.Fragment>
<div
key="chat-container"
style={{
marginTop: "" + this.state.marginTop + "px",
height: "calc(100% - " + this.state.marginTop + "px)",
display: this.state.activeTab === "chat" ? "block" : "none",
}}
>
<ChatMenu
onNewGameState={this.onNewGameState}
gameState={
this.state.member && this.state.gameStates
? this.state.gameStates.find((gs) => {
return (
gs.Properties.Nation === this.state.member.Nation
);
})
: null
}
isActive={this.state.activeTab === "chat"}
unreadMessages={this.setUnreadMessages}
phases={this.state.phases}
game={this.state.game}
parent={this}
/>
</div>
{this.state.game.Properties.Started ? (
<div
key="orders-container"
style={{
marginTop: "" + this.state.marginTop + "px",
height: "calc(100% - " + this.state.marginTop + "px)",
display: this.state.activeTab === "orders" ? "flex" : "none",
flexDirection: "column",
justifyContent: "space-between",
}}
>
<OrderList
isActive={this.state.activeTab === "orders"}
member={this.state.member}
phase={this.state.activePhase}
corroboration={this.state.corroboration}
newPhaseStateHandler={(phaseState) => {
this.setState((state, props) => {
state = Object.assign({}, state);
state.member.NewestPhaseState = phaseState.Properties;
return state;
});
if (this.props.onChangeReady) {
this.props.onChangeReady();
}
}}
variant={this.state.variant}
/>
</div>
) : (
""
)}
<GamePlayers
gameStates={this.state.gameStates}
game={this.state.game}
variant={this.state.variant}
onNewGameState={this.onNewGameState}
parentCB={(c) => {
this.gamePlayersDialog = c;
}}
/>
<PreliminaryScores
phases={this.state.phases}
variant={this.state.variant}
parentCB={(c) => {
this.preliminaryScores = c;
}}
/>
</React.Fragment>
{!this.state.game.Properties.Started ? (
<React.Fragment>
<NationPreferencesDialog
parentCB={(c) => {
this.nationPreferencesDialog = c;
}}
onSelected={null}
/>
<MetadataDialog
game={this.state.game}
parentCB={(c) => {
this.metadataDialog = c;
}}
/>
</React.Fragment>
) : (
""
)}
{!this.state.member ||
!this.state.game.Properties.Started ||
this.state.game.Properties.Mustered ? (
""
) : (
<MusteringPopup
viewOrders={(_) => {
this.setState({
activeTab: "orders",
readyReminder: false,
});
}}
/>
)}
<GameResults
onNewGameState={this.onNewGameState}
gameState={
this.state.member && this.state.gameStates
? this.state.gameStates.find((gs) => {
return gs.Properties.Nation === this.state.member.Nation;
})
: null
}
game={this.state.game}
variant={this.state.variant}
parentCB={(c) => {
this.gameResults = c;
}}
/>
<Snackbar
anchorOrigin={{
vertical: "bottom",
horizontal: "center",
}}
open={this.state.readyReminder}
autoHideDuration={30000}
onClose={(_) => {
this.setState({ readyReminder: false });
}}
message={[
<Typography key="ready-warning">
You haven't confirmed your orders yet.
{this.state.game.Properties.Mustered
? ""
: " For the game to start, all players have to confirm as ready to play."}
</Typography>,
].concat(
this.state.phaseMessages.map((m) => {
return <Typography key={m}>{m}</Typography>;
})
)}
action={
<React.Fragment>
<Button
color="secondary"
size="small"
onClick={(_) => {
this.setState({
activeTab: "orders",
readyReminder: false,
});
}}
>
View orders
</Button>
<IconButton
size="small"
aria-label="close"
color="inherit"
onClick={(_) => {
this.setState({ readyReminder: false });
}}
>
<CloseIcon />
</IconButton>
</React.Fragment>
}
/>
</React.Fragment>
);
} else {
return "";
}
}
Example #18
Source File: Menu.js From qasong with ISC License | 4 votes |
function MobileMenu({ queueLength, setShowAboutUs, setShowSettings, setShowFeedback }) {
const classes = useStyles();
let history = useHistory();
const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState(null);
const isMobileMenuOpen = Boolean(mobileMoreAnchorEl);
const handleMobileMenuClose = () => {
setMobileMoreAnchorEl(null);
};
const handleMobileMenuOpen = (event) => {
setMobileMoreAnchorEl(event.currentTarget);
};
function handleQueueButtonClick() {
history.push("/queue");
handleMobileMenuClose();
}
function handleBillboardClick() {
history.push("/billboard");
handleMobileMenuClose();
}
function handlePlaylistClick() {
history.push("/playlists");
handleMobileMenuClose();
}
function handleSettingsClick() {
setShowSettings(true);
history.push("/");
}
function handleAboutUsClick() {
setShowAboutUs(true);
history.push("/");
}
function handleFeedbackClick() {
setShowFeedback(true);
history.push("/");
handleMobileMenuClose();
}
const mobileMenuId = "primary-search-account-menu-mobile";
return (
<div>
<Menu
anchorEl={mobileMoreAnchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
id={mobileMenuId}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "right",
}}
open={isMobileMenuOpen}
onClose={handleMobileMenuClose}
className={classes.backdrop}
>
{/* QUEUE */}
<MenuItem onClick={handleQueueButtonClick}>
queue
<IconButton target="_blank" color="inherit" size="small">
<Badge badgeContent={queueLength} color="secondary">
<QueueMusicIcon />
</Badge>
</IconButton>
</MenuItem>
<MenuItem onClick={handlePlaylistClick}>playlists</MenuItem>
<MenuItem onClick={handleBillboardClick}>billboard top 100</MenuItem>
<MenuItem onClick={handleSettingsClick}>settings</MenuItem>
<MenuItem onClick={handleFeedbackClick}>feedback</MenuItem>
<MenuItem onClick={handleAboutUsClick}>about us</MenuItem>
</Menu>
<IconButton
aria-label="show more"
aria-controls={mobileMenuId}
aria-haspopup="true"
onClick={handleMobileMenuOpen}
color="inherit"
>
<Badge badgeContent={queueLength} color="secondary">
<MoreIcon style={{ fontSize: 36 }} />
</Badge>
</IconButton>
</div>
);
}
Example #19
Source File: GameListElement.js From dipact with GNU General Public License v3.0 | 4 votes |
render() {
const { classes } = this.props;
let itemKey = 0;
let buttons = [];
if (
this.state.game.Properties.Open &&
this.state.game.Properties.ActiveBans &&
this.state.game.Properties.ActiveBans.length > 0
) {
buttons.push(
<Typography key="banned-notice" style={noticeClass}>
You can't join because you banned or are banned by a player.
</Typography>
);
}
if (
!this.state.game.Properties.Closed &&
this.state.game.Properties.FailedRequirements
) {
buttons.push(
<Typography
variant="subtitle2"
key="requirement-notice"
style={noticeClass}
>
You can't join this game because{" "}
{this.state.game.Properties.FailedRequirements.map((req) => {
return this.failureExplanations()[req];
}).join(" ")}
</Typography>
);
}
if (!this.state.dead) {
buttons.push(
<Button
variant="outlined"
style={{
marginRight: "16px",
minWidth: "100px",
marginBottom: "4px",
}}
color="primary"
onClick={this.viewGame}
key={itemKey++}
>
View
</Button>
);
if (this.state.member) {
buttons.push(
<Button
variant="outlined"
style={{
marginRight: "16px",
minWidth: "100px",
marginBottom: "4px",
}}
color="primary"
onClick={this.renameGame}
key={itemKey++}
>
Rename
</Button>
);
}
}
let replaceablePlayers = 0;
if (this.state.game.Properties.Members !== null) {
replaceablePlayers = this.state.game.Properties.Members.filter(member =>
member.Replaceable == true
).length;
} else {
replaceablePlayers = 0;
}
if (!this.state.game.Properties.Closed || replaceablePlayers > 0) {
buttons.push(
<Button
variant="outlined"
style={{
marginRight: "16px",
minWidth: "100px",
marginBottom: "4px",
}}
color="primary"
onClick={this.shareNative}
key={itemKey++}
>
Invite
</Button>
);
}
let hasInviteDialog = false;
this.state.game.Links.forEach((link) => {
if (link.Rel === "join") {
if (
this.state.game.Properties.PhaseLengthMinutes < 60 * 12 ||
(this.state.game.Properties.NonMovementPhaseLengthMinutes !== 0 &&
this.state.game.Properties.NonMovementPhaseLengthMinutes < 60 * 12)
) {
buttons.unshift(
<Typography key="deadline-warning" style={warningClass}>
WARNING: This game has short deadlines (less than 12 hours). If it
starts while you're unavailable, you might miss parts of the game
greatly impacting your reliability score.
</Typography>
);
}
if (
!this.state.game.Properties.Private &&
this.state.game.Properties.MinReliability === 0 &&
Globals.userStats.Properties.Reliability >= 10
) {
buttons.unshift(
<Typography key="reliability-warning" style={warningClass}>
WARNING: We advise you to join a different game, because this game
might have (some) absent players. You have high reliability so can
join a better game.
</Typography>
);
}
buttons.push(
<Button
key={itemKey++}
variant="outlined"
color="primary"
style={{ marginRight: "16px", minWidth: "100px" }}
onClick={(_) => {
this.joinGame(link);
}}
>
Join
</Button>
);
} else if (link.Rel === "edit-newest-phase-deadline-at") {
buttons.push(
//TODO: Add confirmdialog.js before we accidentally move a turn forwards.. (how?)
<React.Fragment>
<Divider style={{marginBottom: "4px"}} />
<Button
key={itemKey++}
variant="contained"
color="primary"
style={{
marginRight: "16px",
minWidth: "100px",
marginBottom: "4px",
}}
onClick={(_) => {
this.nextturn(link);
}}
>
End Current Phase
</Button>
<Button
key={itemKey++}
variant="contained"
color="primary"
style={{
marginRight: "16px",
minWidth: "100px",
marginBottom: "4px",
}}
onClick={(_) => {
this.reschedule(link);
}}
>
Change deadline
</Button>
</React.Fragment>
);
} else if (link.Rel === "leave") {
buttons.push(
<Button
key={itemKey++}
variant="outlined"
color="primary"
style={{
marginRight: "16px",
minWidth: "100px",
marginBottom: "4px",
}}
onClick={(_) => {
this.leaveGame(link);
}}
>
Leave
</Button>
);
} else if (link.Rel === "delete-game") {
buttons.push(
//TODO: add confirmdialog.js before we accidentally DELETE THE WHOLE (ONGOING) GAME (how)?
<Button
key={itemKey++}
variant="outlined"
color="primary"
style={{
marginRight: "16px",
minWidth: "100px",
marginBottom: "4px",
}}
onClick={(_) => {
this.deleteGame(link);
}}
>
Delete
</Button>
);
} else if (
link.Rel === "invite-user" ||
link.Rel.indexOf("uninvite-") === 0
) {
hasInviteDialog = true;
}
});
if (hasInviteDialog) {
buttons.push(
<Button
key={itemKey++}
variant="contained"
color="primary"
style={{
marginRight: "16px",
minWidth: "100px",
marginBottom: "4px",
}}
onClick={(_) => {
this.manageInvitations();
}}
>
Assign players
</Button>
);
}
const buttonDiv = (
<div
key={itemKey++}
style={{
dispay: "flex",
justifyContent: "space-evenly",
marginBottom: "8px",
}}
>
{buttons}
</div>
);
let summary = (
<div
style={{
display: "flex",
flexDirection: "column",
width: "100%",
marginTop: "8px",
}}
>
{((_) => {
if (this.state.game.Properties.Started && replaceablePlayers == 0) {
return (
<React.Fragment>
{/* IF STARTED */}
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
}}
>
{this.state.member && this.state.member.UnreadMessages > 0 ? (
<Badge
key={itemKey++}
badgeContent={this.state.member.UnreadMessages}
color="primary"
style={{
maxWidth: "calc(100% - 70px)",
}}
>
<Typography
textroverflow="ellipsis"
noWrap
style={{
color: "rgba(40, 26, 26, 1)",
}}
>
{helpers.gameDesc(this.state.game)}
</Typography>
</Badge>
) : (
<Typography
key={itemKey++}
textroverflow="ellipsis"
noWrap={true}
style={{
minWidth: "60px",
color: "rgba(40, 26, 26, 1)",
}}
>
{helpers.gameDesc(this.state.game)}
</Typography>
)}
<div
id="Timer"
key={itemKey++}
style={{
alignSelf: "center",
display: "flex",
alignItems: "center",
color: "#281A1A",
}}
>
{this.state.member &&
this.state.game.Properties.Started &&
!this.state.game.Properties.Finished ? (
this.state.member.NewestPhaseState.OnProbation ? (
<SvgIcon>
<path
d="M2.98188996,2.24133335 L21.3666663,20.6261097 L20.0261097,21.9666663 L19.0573333,20.998 L19,21 L5,21 C3.95,21 3.0822314,20.1799587 3.00551277,19.1486946 L3,19 L3,5 L3.00233335,4.942 L1.64133335,3.58188996 L2.98188996,2.24133335 Z M12,1 C13.235,1 14.2895,1.7581 14.75196,2.828465 L14.82,3 L19,3 C20.05,3 20.9177686,3.82004132 20.9944872,4.85130541 L21,5 L21,17.963 L16.037,13 L17,13 L17,11 L14.037,11 L12.037,9 L17,9 L17,7 L10.037,7 L6.037,3 L9.18,3 C9.579,1.898 10.5917,1.0848 11.80656,1.006235 L12,1 Z M13.0593333,15 L7,15 L7,17 L15.0593333,17 L13.0593333,15 Z M11.0593333,13 L9.06033335,11 L7,11 L7,13 L11.0593333,13 Z M12,3 C11.45,3 11,3.45 11,4 C11,4.55 11.45,5 12,5 C12.55,5 13,4.55 13,4 C13,3.45 12.55,3 12,3 Z"
id="Shape"
fill="#b71c1c"
fillRule="nonzero"
></path>
</SvgIcon>
) : this.state.member.NewestPhaseState.ReadyToResolve ? (
<SvgIcon>
<path
d="M9,0 C10.3,0 11.4,0.84 11.82,2 L11.82,2 L16,2 C17.1045695,2 18,2.8954305 18,4 L18,4 L18,18 C18,19.1045695 17.1045695,20 16,20 L16,20 L2,20 C0.8954305,20 0,19.1045695 0,18 L0,18 L0,4 C0,2.8954305 0.8954305,2 2,2 L2,2 L6.18,2 C6.6,0.84 7.7,0 9,0 Z M13.4347826,7 L7.70608696,12.7391304 L4.56521739,9.60869565 L3,11.173913 L7.70608696,15.8695652 L15,8.56521739 L13.4347826,7 Z M9,2 C8.44771525,2 8,2.44771525 8,3 C8,3.55228475 8.44771525,4 9,4 C9.55228475,4 10,3.55228475 10,3 C10,2.44771525 9.55228475,2 9,2 Z"
fill="#281A1A"
id="Combined-Shape"
></path>
</SvgIcon>
) : (
<StartedAtIcon />
)
) : (
""
)}
<Typography
variant="body2"
style={{
paddingLeft: "2px",
color: "rgba(40, 26, 26, 1)",
}}
>
{this.state.game.Properties.Finished
? helpers.minutesToDuration(
-this.state.game.Properties.FinishedAgo /
1000000000 /
60,
true
)
: helpers.minutesToDuration(
this.state.game.Properties.NewestPhaseMeta[0]
.NextDeadlineIn /
1000000000 /
60,
true
)}
</Typography>
</div>
</div>
<div key={itemKey++} style={secondRowSummaryClass}>
<Typography
textroverflow="ellipsis"
noWrap={true}
display="inline"
variant="caption"
id="variant"
style={secondRowSummaryColorClass}
>
{this.state.game.Properties.Variant}{" "}
{helpers.phaseLengthDisplay(this.state.game.Properties)}
</Typography>
<div style={summaryIconsAndPhaseClass}>
<div style={summaryIconsClass}>{this.getIcons()}</div>
<Typography
variant="caption"
style={secondRowSummaryColorClass}
>
{this.state.game.Properties.NewestPhaseMeta[0].Season}{" "}
{this.state.game.Properties.NewestPhaseMeta[0].Year},{" "}
{this.state.game.Properties.NewestPhaseMeta[0].Type}
</Typography>
</div>
</div>
{!this.state.member || this.state.game.Properties.Mustered ? (
""
) : (this.state.game.Properties.Members || []).find((m) => {
return m.User.Id === Globals.user.Id;
}).NewestPhaseState.ReadyToResolve ? (
<Typography
className={this.props.classes.sixteenBySixteenClass}
>
Confirmed ready <ConfirmedReadyIcon />
</Typography>
) : (
<Button
variant="outlined"
style={{
marginRight: "16px",
minWidth: "100px",
marginBottom: "4px",
}}
color="primary"
onClick={(ev) => {
ev.stopPropagation();
helpers
.safeFetch(
helpers.createRequest(
"/Game/" +
this.state.game.Properties.ID +
"/Phase/" +
this.state.game.Properties.NewestPhaseMeta[0]
.PhaseOrdinal +
"/PhaseState",
{
headers: {
"Content-Type": "application/json",
},
method: "PUT",
body: JSON.stringify({
ReadyToResolve: true,
}),
}
)
)
.then(this.reloadGame);
}}
key={itemKey++}
>
Confirm ready
</Button>
)}
</React.Fragment>
);
} else {
return (
<React.Fragment>
{/* IF STARTED */}
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
}}
>
<Typography
key={itemKey++}
textroverflow="ellipsis"
noWrap={true}
style={{}}
>
{helpers.gameDesc(this.state.game)}
</Typography>
<div
id="Join"
key={itemKey++}
style={{
alignSelf: "center",
display: "flex",
alignItems: "center",
}}
>
<NumMembersIcon style={replaceablePlayers == 0 ? {color: "primary"} : {color: "red"} } />
<Typography variant="body2" style={replaceablePlayers == 0 ? { paddingLeft: "2px", } : { paddingLeft: "2px", color: "red"}}>
{replaceablePlayers == 0 ? this.state.game.Properties.NMembers : this.state.game.Properties.NMembers - replaceablePlayers}/
{this.variant.Properties.Nations.length}{" "}
</Typography>
</div>
</div>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
}}
>
<Typography
textroverflow="ellipsis"
noWrap={true}
display="inline"
variant="caption"
style={{
color: "rgba(40, 26, 26, 0.7)",
}}
>
{this.state.game.Properties.Variant}{" "}
{helpers.phaseLengthDisplay(this.state.game.Properties)}
</Typography>
<div> {this.getIcons()}</div>
</div>
</React.Fragment>
);
}
})()}
<div></div>
</div>
);
let gameView = (
<Zoom in={this.state.viewOpen} mountOnEnter unmountOnExit>
<div
style={{
position: "fixed",
zIndex: 1300,
right: 0,
bottom: 0,
top: 0,
left: 0,
background: "#ffffff",
}}
>
<Game
onChangeReady={this.reloadGame}
onJoinGame={this.reloadGame}
onLeaveGame={(_) => {
if (this.state.game.Properties.Members.length > 1) {
this.reloadGame();
} else {
this.setState({ dead: true });
}
}}
unreadMessagesUpdate={this.reloadGame}
gamePromise={(reload) => {
if (reload) {
return helpers
.safeFetch(
helpers.createRequest(
this.state.game.Links.find((l) => {
return l.Rel === "self";
}).URL
)
)
.then((resp) => resp.json());
} else {
return new Promise((res, rej) => {
res(this.state.game);
});
}
}}
close={this.closeGame}
/>
</div>
</Zoom>
);
if (this.props.summaryOnly) {
return (
<React.Fragment>
<div style={{ width: "100%" }} onClick={this.viewGame}>
{summary}
</div>
{this.state.viewOpen ? gameView : ""}
</React.Fragment>
);
}
return (
<React.Fragment>
<Accordion
key="game-details"
onChange={(ev, exp) => {
this.setState({ expanded: exp });
}}
square
style={{
border: "none",
boxShadow: "none",
padding: "0px",
margin: "0px",
}}
>
<AccordionSummary
classes={{
root: classes.accordionSummaryRoot,
content: classes.accordionSummaryContent,
}}
expandIcon={<ExpandIcon />}
>
{summary}
</AccordionSummary>
<AccordionDetails className={classes.accordionDetails}>
{this.state.expanded ? (
<div>
<div
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
flexWrap: "wrap",
maxWidth: "960px",
width: "100%",
marginBottom: "16px",
}}
>
<div
style={{
maxWidth: "460px",
}}
>
{buttonDiv}
{this.state.dead ? (
<Typography style={{ color: "red" }}>Deleted</Typography>
) : (
""
)}
<GameMetadata
game={this.state.game}
withKickButtons={true}
reloadGame={this.reloadGame}
/>
</div>
</div>
<Divider />
</div>
) : (
""
)}
</AccordionDetails>
</Accordion>
{this.state.viewOpen ? gameView : ""}
<NationPreferencesDialog
parentCB={(c) => {
this.nationPreferencesDialog = c;
}}
onSelected={null}
/>
{this.state.member ? (
<RenameGameDialog
onRename={this.reloadGame}
game={this.state.game}
parentCB={(c) => {
this.renameGameDialog = c;
}}
/>
) : (
""
)}
{this.state.game.Properties.GameMaster &&
this.state.game.Properties.GameMaster.Id === Globals.user.Id ? (
<React.Fragment>
<RescheduleDialog
parentCB={(c) => {
this.rescheduleDialog = c;
}}
onSubmit={this.onRescheduleSubmit}
/>
<ManageInvitationsDialog
game={this.state.game}
parentCB={(c) => {
this.manageInvitationsDialog = c;
}}
reloadGame={this.reloadGame}
/>
</React.Fragment>
) : (
""
)}
</React.Fragment>
);
}
Example #20
Source File: Header.js From facebook-clone with MIT License | 4 votes |
Header = () => {
const classes = Style();
const dispatch = useDispatch();
const mode = useSelector((state) => state.util);
const { photoURL } = useSelector((state) => state.user);
const changeTheme = () => {
dispatch(ToggleTheme());
};
const logout = () => {
auth.signOut();
};
return (
<Paper elevation={0} style={{ borderRadius: 0, width: "100%", height: "100%" }}>
<Grid container className={classes.header}>
{/*----Logo & Search icon--------*/}
<Hidden xsDown>
<Grid item className={classes.header__logo} sm={2} md={3}>
<img className={classes.logo__image} src={logo} alt="facebook-logo" />
<Hidden smDown>
<div className={classes.logo__search}>
<SearchIcon />
<input placeholder="Search facebook ..." />
</div>
</Hidden>
</Grid>
</Hidden>
{/*----Nav-Bar--------*/}
<Grid item className={classes.header__nav} xs={12} sm={8} md={6}>
<div className={`${classes.nav__links} ${classes.nav__links__specail}`}>
<Avatar src={logo} />
</div>
<div className={classes.nav__links}>
<HomeOutlined />
</div>
<div className={classes.nav__links}>
<PlayCircleFilledWhiteOutlined />
</div>
<Hidden xsDown>
<div className={classes.nav__links}>
<StoreMallDirectoryOutlined />
</div>
<div className={classes.nav__links}>
<SupervisedUserCircleOutlined />
</div>
</Hidden>
<div className={classes.nav__links} onClick={changeTheme}>
{mode ? <Brightness4Icon /> : <BrightnessHighIcon />}
</div>
<div className={`${classes.nav__links} ${classes.nav__links__specail}`}>
<Avatar src={photoURL} onClick={logout} />
</div>
</Grid>
{/*----Userinfo and options--------*/}
<Hidden xsDown>
<Grid item className={classes.header__userinfo} sm={2} md={3}>
<Tooltip
placement="left"
TransitionComponent={Zoom}
TransitionProps={{ timeout: 300 }}
title={"logout"}
arrow
>
<Avatar src={photoURL} onClick={logout} />
</Tooltip>
<Hidden smDown>
<div className={classes.userinfo__options}>
<AddIcon />
<TelegramIcon />
<Badge badgeContent={10} max={9} {...defaultProps} />
<ArrowDropDownRoundedIcon />
</div>
</Hidden>
</Grid>
</Hidden>
</Grid>
</Paper>
);
}
Example #21
Source File: ListUrls.js From FireShort with MIT License | 4 votes |
export default function ListUrls(props) {
const classes = useStyles();
const history = useHistory();
const [page, setPage] = React.useState(0);
const [rowsPerPage, setRowsPerPage] = React.useState(10);
const handleChangePage = (event, newPage) => {
setPage(newPage);
};
const handleChangeRowsPerPage = (event) => {
setRowsPerPage(+event.target.value);
setPage(0);
};
return (
<Container className={classes.cardGrid} maxWidth="lg">
<Paper className={classes.root}>
<TableContainer className={classes.container}>
<Table stickyHeader aria-label="sticky table">
<TableHead>
<TableRow>
<TableCell
key="curl"
align="left"
style={{
minWidth: "100px",
}}
>
Short URL
</TableCell>
<TableCell
key="action"
align="center"
style={{
minWidth: "100px",
}}
>
Action
</TableCell>
<TableCell
key="lurl"
align="left"
style={{ minWidth: "100px" }}
>
Long URL
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{props.shortUrls
.slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)
.map((card) => {
return (
<TableRow hover role="checkbox" tabIndex={-1} key={card.id}>
<TableCell
key="curl"
align="left"
style={{ minWidth: "100px" }}
>
<Tooltip title="Copy to clipboard">
<Button
startIcon={<FileCopyOutlinedIcon />}
onClick={() => {
navigator.clipboard.writeText(
window.location.origin + "/" + card.data.curl
);
}}
classes={{ label: classes.label }}
>
{card.data.curl}
</Button>
</Tooltip>
<Tooltip title={card.data.hits + " Hits"}>
<IconButton onClick={() => { props.openHits(card.data.curl) }} style={{ cursor: "pointer" }}>
<Badge
badgeContent={card.data.hits}
color="secondary"
max={Infinity}
showZero
>
<OpenInBrowser />
</Badge>
</IconButton>
</Tooltip>
</TableCell>
<TableCell
key="action"
align="right"
style={{ minWidth: "100px" }}
>
<ButtonGroup variant="outlined" color="default">
<Tooltip title="Preview link">
<Button
size="small"
color="primary"
href={card.data.lurl}
target="_blank"
>
<VisibilityIcon />
</Button>
</Tooltip>
<Tooltip title="Analytics">
<Button
size='small'
disabled={!card.data.track}
onClick={() => history.push(`/analytics/${card.data.curl}`)}
>
<AnalyticsIcon />
</Button>
</Tooltip>
<Tooltip title="Edit link">
<Button
size="small"
onClick={() =>
props.handleEditShortUrl(card.data.curl)
}
>
<EditIcon />
</Button>
</Tooltip>
<Tooltip title="Delete link">
<Button
size="small"
color="secondary"
onClick={() =>
props.handleDeleteShortUrl(card.data.curl)
}
>
<DeleteForeverIcon />
</Button>
</Tooltip>
<Tooltip title="Toggle link protection">
<Button
size="small"
color="default"
onClick={() => props.toggleSecurity(card.data.curl)}
>
{card.data.locked ? <LockIcon /> : <LockOpenIcon />}
</Button>
</Tooltip>
</ButtonGroup>
</TableCell>
<TableCell
key="lurl"
align="left"
style={{ minWidth: "100px" }}
>
<Box
bgcolor="text.primary"
color="background.paper"
p={2}
style={{
overflowX: "auto",
overflowY: "hidden",
whiteSpace: "nowrap",
}}
>
{card.data.lurl}
</Box>
</TableCell>
</TableRow>
);
})}
</TableBody>
</Table>
</TableContainer>
<TablePagination
rowsPerPageOptions={[10, 25, 100]}
component="div"
count={props.shortUrls.length}
rowsPerPage={rowsPerPage}
page={page}
onChangePage={handleChangePage}
onChangeRowsPerPage={handleChangeRowsPerPage}
/>
</Paper>
</Container>
);
}
Example #22
Source File: nav-menu.spec.js From horondi_admin with MIT License | 4 votes |
describe('Nav menu test', () => {
const useDispatchMock = jest.spyOn(reactRedux, 'useDispatch');
const mockHandleDrawerToggle = jest.fn();
let wrapper;
beforeEach(() => {
useDispatchMock.mockReturnValue(mockHandleDrawerToggle);
wrapper = mount(
<Router>
<NavMenu width={mockWidth} />
</Router>
);
});
afterEach(() => {
wrapper.unmount();
});
it('Should render component', () => {
expect(wrapper).toBeDefined();
});
it('Should render Drawer', () => {
expect(wrapper.exists(Drawer)).toBe(true);
});
it('Should render Divider component', () => {
expect(wrapper.exists(Divider)).toBe(true);
});
it('Should render List component', () => {
expect(wrapper.exists(List)).toBe(true);
});
it('Should render ListItem component', () => {
expect(wrapper.exists(ListItem)).toBe(true);
});
it('Should render ListItemIcon component', () => {
expect(wrapper.exists(ListItemIcon)).toBe(true);
});
it('Should render Collapse component', () => {
expect(wrapper.exists(Collapse)).toBe(true);
});
it('Should render ListItemText component and it should be string', () => {
expect(typeof wrapper.find(ListItemText).at(0).text()).toBe('string');
});
it('Should render Badge component for Запитання покупців item', () => {
wrapper.find(ListItemText).at(0).text() === clientsQuestions &&
expect(wrapper.exists(Badge)).toBe(true);
});
it("Should be text 'Домашня сторінка'", () => {
expect(wrapper.find(ListItemText).at(0).text()).toBe(homePage);
});
it('Should render ExpandLess when click on Клієнти', () => {
wrapper.find(ListItem).at(8).invoke('onClick')();
expect(wrapper.exists(ExpandLess)).toBe(true);
});
it('Should render ExpandLess when click on Каталог', () => {
wrapper.find(ListItem).at(9).invoke('onClick')();
expect(wrapper.exists(ExpandLess)).toBe(true);
});
it('Should render ExpandLess when click on Сертифікати', () => {
wrapper.find(ListItem).at(10).invoke('onClick')();
expect(wrapper.exists(ExpandLess)).toBe(true);
});
it('Should render ExpandLess when click on Конструктор', () => {
wrapper.find(ListItem).at(11).invoke('onClick')();
expect(wrapper.exists(ExpandLess)).toBe(true);
});
it('Should render ExpandLess when click on Статичні сторінки', () => {
wrapper.find(ListItem).at(11).invoke('onClick')();
expect(wrapper.exists(ExpandLess)).toBe(true);
});
it('Should render ExpandMore by default', () => {
expect(wrapper.exists(ExpandMore)).toBe(true);
});
it('Should handle click on ListItem component', () => {
wrapper.find(ListItem).at(0).invoke('onClick')();
expect(mockHandleDrawerToggle).toHaveBeenCalledTimes(2);
});
it('Should handle close Drawer', () => {
wrapper.find(Drawer).prop('onClose')();
expect(mockHandleDrawerToggle).toHaveBeenCalledTimes(1);
});
});
Example #23
Source File: OftadehAppBar.jsx From oftadeh-react-admin with MIT License | 4 votes |
OftadehAppBar = (props) => {
const classes = useStyles(props);
const { open, handleDrawerToggle, handleRightPanelOpen } = React.useContext(
NavigationContext
);
const { setThemeName, curThemeName } = React.useContext(ThemeContext);
return (
<AppBar
position="fixed"
className={clsx(classes.appBar, {
[classes.appBarShift]: open,
})}
>
<Toolbar>
<IconButton
color="inherit"
aria-label="open drawer"
onClick={handleDrawerToggle}
edge="start"
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
inputProps={{ "aria-label": "search" }}
/>
</div>
<div className={classes.grow} />
<div className={classes.appbarSection}>
<IconButton
aria-haspopup="true"
onClick={() =>
curThemeName === "dark"
? setThemeName("light")
: setThemeName("dark")
}
color="inherit"
>
{curThemeName === "dark" ? (
<Brightness7Icon />
) : (
<Brightness4Icon />
)}
</IconButton>
<div className={classes.appbarToday}>
<IconButton
aria-haspopup="true"
onClick={(event) => handleRightPanelOpen(event, 0)}
color="inherit"
>
<TodayIcon />
</IconButton>
<IconButton
aria-haspopup="true"
onClick={(event) => handleRightPanelOpen(event, 2)}
aria-label="show 4 new messages"
color="inherit"
>
<Badge badgeContent={4} color="secondary">
<MailIcon />
</Badge>
</IconButton>
</div>
<IconButton
aria-haspopup="true"
onClick={(event) => handleRightPanelOpen(event, 1)}
aria-label="show 17 new notifications"
color="inherit"
>
<Badge badgeContent={17} color="secondary">
<NotificationsIcon />
</Badge>
</IconButton>
<OftadehAvatarMenu />
</div>
</Toolbar>
</AppBar>
);
}
Example #24
Source File: products-filters-container.js From horondi_admin with MIT License | 4 votes |
ProductsFiltersContainer = ({
buttonName,
labels,
productFilter,
list,
filterHandler,
clearFilter
}) => {
const styles = useStyles();
const { filters } = useSelector(({ Products }) => ({
filters: Products.filters
}));
const { categoryFilter } = filters;
const formGroupOptions = list.map((item, idx) => {
const condition = item._id || item;
return (
<MenuItem key={condition} value={condition}>
<Checkbox
size='small'
checked={!!productFilter.find((filter) => filter === condition)}
/>
<ListItemText
primary={labels.length ? labels[idx] : item}
className={styles.menuItems}
/>
</MenuItem>
);
});
const renderFilters = useMemo(
() => (selected) =>
buttonName === CATEGORIES
? list
.filter(({ _id }) =>
categoryFilter.some((category) => category === _id)
)
.map(({ name }) => name[0].value)
.join(', ')
: selected.join(', '),
[categoryFilter, list, buttonName]
);
return (
<Grid
item
xs={12}
sm={6}
md={6}
lg={3}
container
alignItems='center'
className={styles.container}
>
<Badge
badgeContent={productFilter.length}
color='error'
anchorOrigin={badgePosition}
className={styles.badge}
>
{productFilter.length ? (
<Tooltip title={deleteFilter}>
<RemoveCircleOutlineIcon
onClick={clearFilter}
color='error'
className={styles.filterIcon}
/>
</Tooltip>
) : null}
<FormControl className={styles.formControl}>
<InputLabel id='multiple-checkbox-label'>{buttonName}</InputLabel>
<Select
labelId='multiple-checkbox-label'
id='multiple-checkbox'
multiple
MenuProps={MenuProps}
value={productFilter}
onChange={filterHandler}
input={<Input />}
renderValue={renderFilters}
className={styles.menuItems}
>
{formGroupOptions}
</Select>
</FormControl>
</Badge>
</Grid>
);
}
Example #25
Source File: product-options-container.js From horondi_admin with MIT License | 4 votes |
ProductOptionsContainer = ({
selectedOptions,
setOptions,
additions,
toggleFieldsChanged
}) => {
const styles = useStyles();
const productOptions = useSelector(({ Products }) => Products.productOptions);
const { sizes, bottomMaterials } = productOptions;
const handleOptionChange = (event, name) => {
toggleFieldsChanged(true);
setOptions({ ...selectedOptions, [name]: event.target.value });
};
const handleAdditionChange = (event) => {
toggleFieldsChanged(true);
const { name, checked } = event.target;
setOptions({ ...selectedOptions, [name]: checked });
};
const handleDeleteOption = (option, name) => {
toggleFieldsChanged(true);
const currentOption = selectedOptions[option];
const sizeToRemove = currentOption.indexOf(name);
setOptions({
...selectedOptions,
[option]: [
...currentOption.slice(0, sizeToRemove),
...currentOption.slice(sizeToRemove + 1)
]
});
};
const getCardItems = (items, option, labels) =>
items
.filter(({ name }) =>
selectedOptions[option].some((item) => item === name)
)
.map((item) => {
const cardContent = labels.map(({ label, name }) => (
<Typography key={name}>
{label}: {item[name]}
</Typography>
));
const priceDetail = (
<Typography>
{ADDITIONAL_PRICE}: {item.additionalPrice[0].value / 100}
</Typography>
);
return (
<Grid item key={item.name}>
<Card>
<CardContent>
<Grid container justify='flex-end'>
<Tooltip title={DELETE_PRODUCT_BTN} placement='top'>
<IconButton
className={styles.removeIcon}
onClick={() => handleDeleteOption(option, item.name)}
>
<CloseIcon />
</IconButton>
</Tooltip>
</Grid>
{cardContent}
{priceDetail}
</CardContent>
</Card>
</Grid>
);
});
const getOptions = (name, _id) => (
<MenuItem value={name} key={_id}>
{name}
</MenuItem>
);
const sortSizes = (a, b) => {
if (a.name > b.name) {
return -1;
}
if (b.name > a.name) {
return 1;
}
return 0;
};
const sizesOptions = useMemo(
() =>
sizes
.slice()
.sort(sortSizes)
.map(({ name, _id }) => getOptions(name, _id)),
[sizes]
);
const bottomMaterialsOptions = useMemo(
() =>
bottomMaterials.map(({ name, _id }) => getOptions(name[0].value, _id)),
[bottomMaterials]
);
const formattedMaterials = useMemo(
() =>
bottomMaterials.map((item) => ({ ...item, name: item.name[0].value })),
[bottomMaterials]
);
const optionsToMap = useMemo(
() => [sizesOptions, bottomMaterialsOptions],
[sizesOptions, bottomMaterialsOptions]
);
const cardLabels = useMemo(() => [sizeCardsLabels, materialsLabels], []);
const cardOptions = useMemo(
() => [sizes, formattedMaterials],
[sizes, formattedMaterials]
);
return (
<div>
{optionsLabels.map(({ label, name }, idx) => (
<div key={name}>
{!!selectedOptions[name].length && <Box mt={2.5} />}
<Grid container className={styles.select}>
<Grid item>
<Badge
color='error'
anchorOrigin={badgePosition}
badgeContent={selectedOptions[name].length}
>
<FormControl className={styles.formControl}>
<InputLabel id='multiple-checkbox-label'>{label}</InputLabel>
<Select
required
labelId='multiple-checkbox-label'
id='multiple-checkbox'
multiple
value={selectedOptions[name]}
onChange={(e) => handleOptionChange(e, name)}
input={<Input />}
>
{optionsToMap[idx]}
</Select>
</FormControl>
</Badge>
</Grid>
<Grid item container spacing={2} className={styles.gridContainer}>
{getCardItems(cardOptions[idx], name, cardLabels[idx])}
</Grid>
</Grid>
</div>
))}
<Grid container className={styles.checkbox}>
<FormControlLabel
control={
<Checkbox
checked={selectedOptions.additions}
onChange={handleAdditionChange}
name='additions'
color='primary'
/>
}
label={
!!(additions && additions.length) && (
<div>
{additions[0].name[0].value}
<span>
(
<span className={styles.additionalPrice}>
+{additions[0].additionalPrice[0].value / 100}
{` ${UAH}`}
</span>
)
</span>
</div>
)
}
/>
</Grid>
</div>
);
}
Example #26
Source File: TransactionModal.js From akashlytics-deploy with GNU General Public License v3.0 | 4 votes |
export function TransactionModal({ isOpen, onConfirmTransaction, messages, onClose }) {
const [isSendingTransaction, setIsSendingTransaction] = useState(false);
const [tabIndex, setTabIndex] = useState(0);
const [memo, setMemo] = useState("");
const [showMemoWarning, setShowMemoWarning] = useState(false);
const [customGas, setCustomGas] = useState(null); // Set once we calculate fees
const [customFee, setCustomFee] = useState(null); // Set once we calculate fees
const [isSettingCustomFee, setIsCustomFee] = useState(false);
const [isCalculatingFees, setIsCalculatingFees] = useState(true);
const [calculatedFees, setCalculatedFees] = useState(null);
const [currentFee, setCurrentFee] = useState("average");
const { settings } = useSettings();
const { address, selectedWallet, refreshBalance } = useWallet();
const classes = useStyles();
const { enqueueSnackbar, closeSnackbar } = useSnackbar();
const isCustomFeeValid = customFee && parseFloat(customFee) > 0;
const isGasValid = customGas && parseInt(customGas) > 0;
useEffect(() => {
(async () => {
const client = await SigningStargateClient.connectWithSigner(settings.rpcEndpoint, selectedWallet, {
registry: customRegistry,
broadcastTimeoutMs: 300_000 // 5min
});
const gasEstimation = await client.simulate(
address,
messages.map((m) => m.message),
memo
);
const estimatedGas = Math.round(gasEstimation * gasPaddingMultiplier);
const fees = {
low: calculateFee(estimatedGas, gasPrices.low),
average: calculateFee(estimatedGas, gasPrices.average),
high: calculateFee(estimatedGas, gasPrices.high)
};
setCalculatedFees(fees);
setIsCalculatingFees(false);
setCustomFee(uaktToAKT(fees.average.amount[0].amount));
setCustomGas(estimatedGas);
})();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
async function handleSubmit(ev) {
ev.preventDefault();
setIsSendingTransaction(true);
let pendingSnackbarKey = enqueueSnackbar(<Snackbar title="Broadcasting transaction..." subTitle="Please wait a few seconds" showLoading />, {
variant: "info",
autoHideDuration: null
});
try {
// Setup client
const client = await SigningStargateClient.connectWithSigner(settings.rpcEndpoint, selectedWallet, {
registry: customRegistry,
broadcastTimeoutMs: 300_000 // 5min
});
const fee = isSettingCustomFee ? createCustomFee(aktToUakt(customFee), customGas) : calculatedFees[currentFee];
const response = await client.signAndBroadcast(
address,
messages.map((m) => m.message),
fee,
memo
);
const transactionHash = response.transactionHash;
const isError = response.code !== 0;
console.log(response);
if (isError) {
throw new BroadcastingError("Code " + response.code + " : " + response.rawLog, transactionHash);
}
showTransactionSnackbar("Transaction succeeds!", "", transactionHash, "success");
await analytics.event("deploy", "successful transaction");
refreshBalance();
// return response message
onConfirmTransaction(response);
} catch (err) {
console.error(err);
const transactionHash = err.txHash;
let errorMsg = "An error has occured";
await analytics.event("deploy", "failed transaction");
if (err.message.includes("was submitted but was not yet found on the chain")) {
errorMsg = "Transaction timeout";
} else {
try {
const reg = /Broadcasting transaction failed with code (.+?) \(codespace: (.+?)\)/i;
const match = err.message.match(reg);
const log = err.message.substring(err.message.indexOf("Log"), err.message.length);
if (match) {
const code = parseInt(match[1]);
const codeSpace = match[2];
if (codeSpace === "sdk") {
const errorMessages = {
5: "Insufficient funds",
9: "Unknown address",
11: "Out of gas",
12: "Memo too large",
13: "Insufficient fee",
19: "Tx already in mempool",
25: "Invalid gas adjustment"
};
if (code in errorMessages) {
errorMsg = errorMessages[code];
}
}
}
if (log) {
errorMsg += `. ${log}`;
}
} catch (err) {
console.error(err);
}
}
showTransactionSnackbar("Transaction has failed...", errorMsg, transactionHash, "error");
setIsSendingTransaction(false);
} finally {
closeSnackbar(pendingSnackbarKey);
}
}
const showTransactionSnackbar = (snackTitle, snackMessage, transactionHash, snackVariant) => {
enqueueSnackbar(
<Snackbar
title={snackTitle}
subTitle={<TransactionSnackbarContent snackMessage={snackMessage} transactionHash={transactionHash} />}
iconVariant={snackVariant}
/>,
{
variant: snackVariant,
autoHideDuration: 10000
}
);
};
const handleTabChange = (event, newValue) => {
setTabIndex(newValue);
};
const onSetGasClick = (event) => {
event.preventDefault();
setIsCustomFee(!isSettingCustomFee);
};
const onMemoChange = (event) => {
const newValue = event.target.value;
setMemo(newValue);
const splittedValue = (newValue || "").trim().split(" ");
setShowMemoWarning(splittedValue.length === 12 || splittedValue.length === 24);
};
return (
<Dialog
open={isOpen}
onClose={!isSendingTransaction && !isCalculatingFees ? onClose : null}
maxWidth="xs"
fullWidth
aria-labelledby="transaction-modal"
aria-describedby="transaction modal description"
>
<DialogTitle id="transaction-modal">
<span className={classes.title}>Akash Transaction</span>
</DialogTitle>
<DialogContent dividers classes={{ root: classes.tabContent }}>
<AppBar position="static" color="default">
<Tabs
value={tabIndex}
onChange={handleTabChange}
indicatorColor="primary"
textColor="primary"
variant="fullWidth"
aria-label="Akash transaction data"
>
<Tab label="Details" {...a11yProps(`${a11yPrefix}-${0}`)} disabled={isCalculatingFees} />
<Tab label="Data" {...a11yProps(`${a11yPrefix}-${1}`)} disabled={isCalculatingFees} />
</Tabs>
</AppBar>
<TabPanel value={tabIndex} index={0} className={classes.tabPanel}>
<Badge color="primary" badgeContent={messages.length} classes={{ badge: classes.badge }}>
<Typography variant="h4" className={classes.label}>
Messages
</Typography>
</Badge>
<List dense className={classes.messages}>
{messages.map(({ message }, i) => {
return <TransactionMessage key={`message_${i}`} message={message} />;
})}
</List>
<Box padding="1rem 0">
<TextField
label="Memo"
disabled={isSendingTransaction}
value={memo}
onChange={onMemoChange}
type="text"
variant="outlined"
inputProps={{
maxLength: 256
}}
InputProps={{
endAdornment: (
<InputAdornment position="end">
<Tooltip
classes={{ tooltip: classes.tooltip }}
arrow
title="Memo field is usually used for specifying a customer ID for certain centralized exchanges.
Never enter your mnemonic seed phrase / passphrase / password or anything sensitive!
Everything in this field becomes permanently public, accessible by anyone!"
>
{showMemoWarning ? <WarningIcon fontSize="small" color="error" /> : <HelpIcon fontSize="small" color="primary" />}
</Tooltip>
</InputAdornment>
)
}}
classes={{ root: classes.fullWidth }}
/>
</Box>
{isCalculatingFees ? (
<Box display="flex" alignItems="center" justifyContent="center">
<CircularProgress size="24px" color="primary" />
</Box>
) : (
<>
<Box>
<ButtonGroup
size="large"
color="primary"
aria-label="large outlined primary button group"
classes={{ root: classes.fullWidth }}
disabled={isSettingCustomFee}
>
<Button
disabled={isSendingTransaction}
classes={{ root: classes.feeButton, label: classes.feeButtonLabel }}
variant={currentFee === "low" ? "contained" : "outlined"}
onClick={() => setCurrentFee("low")}
>
<Box>Low</Box>
<Box>
<Typography variant="caption">
<PriceValue value={uaktToAKT(calculatedFees.low.amount[0].amount, 4)} showLt />
</Typography>
</Box>
<div className={clsx(classes.feeButtonLabelAmount, { [classes.textWhite]: currentFee === "low" })}>
{uaktToAKT(calculatedFees.low.amount[0].amount, 4)}AKT
</div>
</Button>
<Button
disabled={isSendingTransaction}
classes={{ root: classes.feeButton, label: classes.feeButtonLabel }}
variant={currentFee === "average" ? "contained" : "outlined"}
onClick={() => setCurrentFee("average")}
>
<Box>Avg</Box>
<Box>
<Typography variant="caption">
<PriceValue value={uaktToAKT(calculatedFees.average.amount[0].amount, 4)} showLt />
</Typography>
</Box>
<div className={clsx(classes.feeButtonLabelAmount, { [classes.textWhite]: currentFee === "average" })}>
{uaktToAKT(calculatedFees.average.amount[0].amount, 4)}AKT
</div>
</Button>
<Button
disabled={isSendingTransaction}
classes={{ root: classes.feeButton, label: classes.feeButtonLabel }}
variant={currentFee === "high" ? "contained" : "outlined"}
onClick={() => setCurrentFee("high")}
>
<Box>High</Box>
<Box>
<Typography variant="caption">
<PriceValue value={uaktToAKT(calculatedFees.high.amount[0].amount, 4)} showLt />
</Typography>
</Box>
<div className={clsx(classes.feeButtonLabelAmount, { [classes.textWhite]: currentFee === "high" })}>
{uaktToAKT(calculatedFees.high.amount[0].amount, 4)}AKT
</div>
</Button>
</ButtonGroup>
</Box>
<Box>
{!isSendingTransaction && (
<Typography className={classes.setGasLink}>
<Link href="#" onClick={onSetGasClick}>
Set custom fee
</Link>
</Typography>
)}
{!isSendingTransaction && isSettingCustomFee && (
<>
<Box marginBottom=".5rem">
<TextField
label="Fee (AKT)"
value={customFee}
onChange={(ev) => setCustomFee(ev.target.value)}
type="number"
variant="outlined"
error={!isCustomFeeValid}
inputProps={{
step: 0.001,
min: 0
}}
classes={{ root: classes.fullWidth }}
/>
</Box>
<Box>
<TextField
label="Gas"
value={customGas}
onChange={(ev) => setCustomGas(ev.target.value)}
type="number"
variant="outlined"
error={!isGasValid}
inputProps={{
step: 1,
min: 1
}}
classes={{ root: classes.fullWidth }}
/>
</Box>
</>
)}
</Box>
</>
)}
</TabPanel>
<TabPanel value={tabIndex} index={1} className={clsx(classes.tabPanel)}>
<Box className={classes.messagesData}>
{JSON.stringify(
messages.map((m) => m.message),
null,
2
)}
</Box>
</TabPanel>
</DialogContent>
<DialogActions>
<Button variant="outlined" color="secondary" onClick={onClose} disabled={isSendingTransaction} type="button" classes={{ root: classes.actionButton }}>
Reject
</Button>
<Button
variant="contained"
color="primary"
onClick={handleSubmit}
disabled={isSendingTransaction || !isGasValid || isCalculatingFees}
classes={{ root: classes.actionButton }}
>
{isSendingTransaction ? <CircularProgress size="24px" color="primary" /> : "Approve"}
</Button>
</DialogActions>
</Dialog>
);
}
Example #27
Source File: nav-menu.js From horondi_admin with MIT License | 4 votes |
NavMenu = ({ width }) => {
const classes = useStyles();
const dispatch = useDispatch();
const [navbarTab, setNavbarTab] = useState({
clientTab: false,
catalogTab: false,
certificatesTab: false,
constructorTab: false,
staticTab: false,
materialsTab: false,
promoTab: false
});
const staticArray = {
clientTab: false,
catalogTab: false,
certificatesTab: false,
constructorTab: false,
staticTab: false,
materialsTab: false,
promoTab: false
};
const { sideMenuStatus, pendingQuestionsCount } = useSelector(
({ Theme, EmailQuestions }) => ({
sideMenuStatus: Theme.sideMenuStatus,
pendingQuestionsCount: EmailQuestions.pendingCount
})
);
const returnedList = (pathTitle, pathTo, PathIcon, nested) => (
<ListItem
onClick={() => {
dispatch(setSideMenuStatus(!sideMenuStatus));
dispatch(resetPagination());
if (!nested) {
setNavbarTab({
...staticArray
});
}
}}
button
key={pathTitle}
component={NavLink}
to={pathTo}
className={pathTitle === 'Слайдер' ? classes.sliderTab : nested || null}
activeClassName={classes.selectedCategory}
isActive={(props) => (props ? props.url === pathTo : null)}
>
<ListItemIcon>
<PathIcon />
</ListItemIcon>
<ListItemText primary={pathTitle} />
{pathTitle === titles.emailQuestionsTitles.mainPageTitle && (
<Badge badgeContent={pendingQuestionsCount} color='error' />
)}
</ListItem>
);
const menuItems = config.menuCategories.map((category) =>
returnedList(category[0], category[1], category[2])
);
const materialMenuItems = config.materialMenuCategories.map((category) =>
returnedList(...category, classes.nested)
);
const clientMenuItems = config.clientMenuCategories.map((category) =>
returnedList(category[0], category[1], category[2], classes.nested)
);
const catalogMenuItems = config.catalogMenuCategories.map((category) =>
returnedList(category[0], category[1], category[2], classes.nested)
);
const promoMenuItems = config.promoMenuCategories.map((category) =>
returnedList(...category, classes.nested)
);
const staticPagesMenuItems = config.staticPagesCategories.map((category) =>
returnedList(category[0], category[1], category[2], classes.nested)
);
const constructorPagesMenuItems = config.constructorMenuCategories.map(
(category) =>
returnedList(category[0], category[1], category[2], classes.nested)
);
const certificatesMenuItems = config.certificatesMenuCategories.map(
(category) =>
returnedList(category[0], category[1], category[2], classes.nested)
);
const parentMenuTabsProperties = [
[
() =>
setNavbarTab({
...staticArray,
clientTab: !navbarTab.clientTab
}),
navbarTab.clientTab,
clientMenuItems,
MENU_TABS.CLIENTS,
AccessibilityNewIcon
],
[
() =>
setNavbarTab({
...staticArray,
catalogTab: !navbarTab.catalogTab
}),
navbarTab.catalogTab,
catalogMenuItems,
MENU_TABS.CATALOG,
ImportContactsIcon
],
[
() =>
setNavbarTab({
...staticArray,
certificatesTab: !navbarTab.certificatesTab
}),
navbarTab.certificatesTab,
certificatesMenuItems,
MENU_TABS.CERTIFICATES,
TuneIcon
],
[
() =>
setNavbarTab({
...staticArray,
promoTab: !navbarTab.promoTab
}),
navbarTab.promoTab,
promoMenuItems,
MENU_TABS.PROMOCODE,
PromoIcon
],
[
() =>
setNavbarTab({
...staticArray,
constructorTab: !navbarTab.constructorTab
}),
navbarTab.constructorTab,
constructorPagesMenuItems,
MENU_TABS.CONSTRUCTOR,
AccessibilityNewIcon
],
[
() =>
setNavbarTab({
...staticArray,
materialsTab: !navbarTab.materialsTab
}),
navbarTab.materialsTab,
materialMenuItems,
MENU_TABS.MATERIALS,
ExtensionIcon
],
[
() =>
setNavbarTab({
...staticArray,
staticTab: !navbarTab.staticTab
}),
navbarTab.staticTab,
staticPagesMenuItems,
MENU_TABS.STATIC_PAGES,
LayersIcon
]
];
const parentMenuItems = parentMenuTabsProperties.map((category) => {
const handleClick = category[0];
const stateMenu = category[1];
const subList = category[2];
const primary = category[3];
const ItemIcon = category[4];
return (
<Fragment key={category.toString()}>
<ListItem button onClick={handleClick}>
<ListItemIcon>
<ItemIcon />
</ListItemIcon>
<ListItemText primary={primary} />
{stateMenu ? <ExpandLess /> : <ExpandMore />}
</ListItem>
<Collapse in={stateMenu} timeout='auto' unmountOnExit>
<List>{subList}</List>
</Collapse>
</Fragment>
);
});
const handleDrawerToggle = () => {
dispatch(setSideMenuStatus(!sideMenuStatus));
};
const checkWidth = () =>
TEMPORARY_WIDTHS.find((element) => element === width);
const drawerVariant = checkWidth() ? DRAWER_TEMPORARY : DRAWER_PERMANENT;
return (
<Drawer
id='menuDrawer'
className={classes.drawer}
variant={drawerVariant}
open={sideMenuStatus}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper
}}
>
<div className={classes.toolbar} />
<Divider />
<List>
{menuItems}
{parentMenuItems}
</List>
<Divider />
</Drawer>
);
}
Example #28
Source File: NavAppBar.js From yasn with MIT License | 4 votes |
export default function NavAppBar(props) {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
const [mobileMoreAnchorEl, setMobileMoreAnchorEl] = React.useState(null);
const isMenuOpen = Boolean(anchorEl);
const isMobileMenuOpen = Boolean(mobileMoreAnchorEl);
const [mobileOpen, setMobileOpen] = React.useState(false);
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
const handleProfileMenuOpen = (event) => {
setAnchorEl(event.currentTarget);
};
const handleMobileMenuClose = () => {
setMobileMoreAnchorEl(null);
};
const handleMenuClose = () => {
setAnchorEl(null);
handleMobileMenuClose();
};
const handleMobileMenuOpen = (event) => {
setMobileMoreAnchorEl(event.currentTarget);
};
const handleLogOut = () => {
setMobileMoreAnchorEl(null);
cookies.remove("userCookie");
cookies.remove("userDetails");
window.location.reload();
};
const menuId = "primary-search-account-menu";
const renderMenu = (
<Menu
anchorEl={anchorEl}
anchorOrigin={{ vertical: "top", horizontal: "right" }}
id={menuId}
keepMounted
transformOrigin={{ vertical: "top", horizontal: "right" }}
open={isMenuOpen}
onClose={handleMenuClose}
>
<Link to={`/profile`} className={classes.link}>
<MenuItem onClick={handleMenuClose}>Profile</MenuItem>
</Link>
<MenuItem onClick={handleMenuClose} onClick={handleLogOut}>
Log Out
</MenuItem>
</Menu>
);
const mobileMenuId = "primary-search-account-menu-mobile";
const renderMobileMenu = (
<Menu
anchorEl={mobileMoreAnchorEl}
anchorOrigin={{ vertical: "top", horizontal: "right" }}
id={mobileMenuId}
keepMounted
transformOrigin={{ vertical: "top", horizontal: "right" }}
open={isMobileMenuOpen}
onClose={handleMobileMenuClose}
>
<Link to="/chat" className={classes.link}>
<MenuItem onClick={handleMobileMenuClose}>
<IconButton aria-label="show 4 new mails" color="inherit">
<Badge badgeContent={"ßeta"} color="secondary">
<MailIcon />
</Badge>
</IconButton>
<p>Messages</p>
</MenuItem>
</Link>
<Link to="/add" className={classes.link}>
<MenuItem onClick={handleMobileMenuClose}>
<IconButton aria-label="show 11 new notifications" color="inherit">
{/* <Badge badgeContent={11} color="secondary"> */}
<PostAddIcon />
{/* </Badge> */}
</IconButton>
<p>Add Post</p>
</MenuItem>
</Link>
<Link to={`/profile`} className={classes.link}>
<MenuItem onClick={handleMobileMenuClose}>
<IconButton
aria-label="account of current user"
aria-controls="primary-search-account-menu"
aria-haspopup="true"
color="inherit"
>
<AccountCircle />
</IconButton>
<p>Profile</p>
</MenuItem>
</Link>
<MenuItem onClick={handleLogOut}>
<IconButton aria-label="show 11 new notifications" color="inherit">
<ExitToAppIcon />
</IconButton>
<p>Log Out</p>
</MenuItem>
</Menu>
);
const { container } = props;
const theme = useTheme();
const drawer = (
<div>
<div className={classes.toolbar} />
<List>
<ListItem>
<Typography>Browse by Category</Typography>
</ListItem>
</List>
<Divider />
<List>
{/* <Link to="/home/Project"> */}
<a href="/home/Project">
<ListItem button key={"Projects"}>
<ListItemIcon>
<GitHubIcon />
</ListItemIcon>
<ListItemText primary={"Projects"} />
</ListItem>
</a>
{/* </Link> */}
{/* <Link to="/home/Writings"> */}
<a href="/home/Writings">
<ListItem button key={"Writings"}>
<ListItemIcon>
<CreateIcon />
</ListItemIcon>
<ListItemText primary={"Writings"} />
</ListItem>
</a>
{/* </Link> */}
{/* <Link to="/home/Artwork" onClick={handleTagLink}> */}
<a href="/home/Artwork">
<ListItem button key={"Artwork"}>
<ListItemIcon>
<GestureIcon />
</ListItemIcon>
<ListItemText primary={"Artwork"} />
</ListItem>
</a>
{/* </Link> */}
</List>
<Divider />
<List>
{/* <Link to="/home/Music"> */}
<a href="/home/Music">
<ListItem button key={"Music"}>
<ListItemIcon>
<MusicNoteIcon />
</ListItemIcon>
<ListItemText primary={"Music"} />
</ListItem>
</a>
{/* </Link> */}
{/* <Link to="/home/Dance"> */}
<a href="/home/Dance">
<ListItem button key={"Dance"}>
<ListItemIcon>
<DirectionsWalkIcon />
</ListItemIcon>
<ListItemText primary={"Dance"} />
</ListItem>
</a>
{/* </Link> */}
{/* <Link to="/home/Other"> */}
<a href="/home/Other">
<ListItem button key={"Other"}>
<ListItemIcon>
<CallSplitIcon />
</ListItemIcon>
<ListItemText primary={"Other"} />
</ListItem>
</a>
{/* </Link> */}
</List>
<Divider />
</div>
);
const userCookie = cookies.get("userCookie");
const googleToken = userCookie.Token;
const email = userCookie.Email;
const [searchResults, setSearchResults] = useState([]);
const searchUsers = debounce((searchString) => {
axios
.get(
`${ConnectServerUrl}/searchUsers?` +
queryString.stringify(
{ searchString, googleToken, email },
{ withCredentials: true }
)
)
.then((res) => {
setSearchResults(res.data);
})
.catch(console.log);
}, 400);
const onSearchInputChange = (event) => {
const searchString = event.target.value;
if (searchString) {
searchUsers(searchString);
}
};
return (
<div className={classes.root}>
<CssBaseline />
<div className={classes.grow}>
<AppBar position="fixed" className={classes.appBar}>
<Toolbar>
<IconButton
edge="start"
className={handleDrawerToggle}
color="inherit"
aria-label="open drawer"
onClick={handleDrawerToggle}
// eslint-disable-next-line
className={classes.menuButton}
>
<MenuIcon />
</IconButton>
<Link to="/">
<IconButton edge="start">
<DonutSmallIcon style={{ color: "white" }} />
</IconButton>
</Link>
<Typography className={classes.title} variant="h6" noWrap>
Connect
</Typography>
<div className={classes.search}>
<div className={classes.searchIcon}>
<SearchIcon />
</div>
<Autocomplete
id="free-solo-demo"
freeSolo
clearOnBlur
options={searchResults}
className="searchBox"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
endAdornment: classes.endAdornment,
}}
getOptionLabel={(option) => option.name}
renderOption={(option, state) => (
<Link to={`/user/${option.username}`}>
<Typography>{option.name}</Typography>
</Link>
)}
renderInput={(params) => (
<TextField
{...params}
onChange={onSearchInputChange}
placeholder="Search DAIICTians"
/>
)}
/>
</div>
<div className={classes.grow} />
<div className={classes.sectionDesktop}>
<Link to="/chat">
<IconButton aria-label="show 4 new mails" color="inherit">
<Badge badgeContent={"ßeta"} color="secondary">
<MailIcon />
</Badge>
</IconButton>
</Link>
<Link to="/add">
<IconButton
aria-label="show 17 new notifications"
color="inherit"
>
{/* <Badge badgeContent={17} color="secondary"> */}
<PostAddIcon />
{/* </Badge> */}
</IconButton>
</Link>
<IconButton
edge="end"
aria-label="account of current user"
aria-controls={menuId}
aria-haspopup="true"
onClick={handleProfileMenuOpen}
color="inherit"
>
<AccountCircle />
</IconButton>
</div>
<div className={classes.sectionMobile}>
<IconButton
aria-label="show more"
aria-controls={mobileMenuId}
aria-haspopup="true"
onClick={handleMobileMenuOpen}
color="inherit"
>
<MoreIcon />
</IconButton>
</div>
</Toolbar>
</AppBar>
{renderMobileMenu}
{renderMenu}
</div>
<nav className={classes.drawer} aria-label="mailbox folders">
{/* The implementation can be swapped with js to avoid SEO duplication of links. */}
<Hidden smUp implementation="css">
<Drawer
container={container}
variant="temporary"
anchor={theme.direction === "rtl" ? "right" : "left"}
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown implementation="css">
<Drawer
classes={{
paper: classes.drawerPaper,
}}
variant="permanent"
open
>
{drawer}
</Drawer>
</Hidden>
</nav>
<main className={classes.content}>
{props.children}
{/* <div className={classes.toolbar} /> */}
</main>
</div>
);
}
Example #29
Source File: Drawer.js From inventory-management-web with MIT License | 4 votes |
function NavDrawer({ mobileOpen, setMobileOpen, tabletOpen }) {
const classes = useStyles({ tab: tabletOpen });
const theme = useTheme();
// true if in tablet mode
const tablet = useMediaQuery(theme.breakpoints.only('sm'));
// links and labels for each link in drawer
const [list, setList] = useState({
links: ['/', '/inventory', '/transaction'],
labels: ['Home', 'Inventory', 'Transactions'],
});
// function to handle drawer state on mobile
const handleDrawerToggle = () => {
setMobileOpen(!mobileOpen);
};
// array of drawer icons
const listIcons = [
<HomeIcon className={classes.icons} />,
<ListIcon className={classes.icons} />,
<PersonIcon className={classes.icons} />,
<ReceiptIcon className={classes.icons} />,
];
useEffect(() => {
// Add Admin protected links to the list only if isStaff is true
const isAdmin = localStorage.getItem('isStaff');
if (isAdmin === 'true') {
setList({
labels: ['Home', 'Inventory', 'Employees', 'Transactions'],
links: ['/', '/inventory', '/employee', '/transaction'],
});
}
}, []);
const { expiryListBadge, setExpiryListBadge, update } = useContext(
ExpiryListContext
);
const history = useHistory();
const apiFetch = async () => {
try {
const response = await getEndPoint('/api/explist/', null, history);
const { data } = response;
setExpiryListBadge(data.count);
} catch (e) {
console.log(e);
}
};
// call API on component load
useEffect(() => {
apiFetch();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [update]);
const drawer = (
<div>
<List>
{list.labels.map((text, index) => (
<Link
to={list.links[index]}
className={classes.link}
key={text}
onClick={handleDrawerToggle}
>
<ListItem button key={text}>
<ListItemIcon className={classes.listIcon}>
<Badge
badgeContent={expiryListBadge}
color='primary'
overlap='circle'
className={classes.tabBadge}
invisible={!(text === 'Inventory' && !tabletOpen && tablet)}
>
{listIcons[index]}
</Badge>
</ListItemIcon>
<Badge
badgeContent={expiryListBadge}
color='primary'
overlap='circle'
className={classes.badge}
invisible={text !== 'Inventory'}
>
<ListItemText primary={text} className={classes.listText} />
</Badge>
</ListItem>
</Link>
))}
</List>
</div>
);
return (
<nav className={classes.drawer}>
<Hidden smUp>
<Drawer
variant='temporary'
open={mobileOpen}
onClose={handleDrawerToggle}
classes={{
paper: classes.drawerPaper,
}}
ModalProps={{
keepMounted: true, // Better open performance on mobile.
}}
>
<div className={classes.drawerHeader}>
<IconButton onClick={handleDrawerToggle}>
<ChevronLeftIcon />
</IconButton>
</div>
{drawer}
</Drawer>
</Hidden>
<Hidden xsDown>
<Drawer
classes={{
paper: classes.drawerPaper,
}}
variant='permanent'
open
>
<div className={classes.toolbar} />
{drawer}
</Drawer>
</Hidden>
</nav>
);
}