React - Accessing PhotoURL from Firebase user: Image not displaying - reactjs

Using Material UI components such as Tooltip, IconButton, and Avatar, I've made this:
<Tooltip title="Open settings">
<IconButton
onClick={handleOpenUserMenu}
sx={{ p: 0 }}
>
<img
alt="pfp"
src={auth.currentUser.photoURL}
/>
<Avatar
alt="Google Photo/Initial"
src={auth.currentUser
.photoURL}
/>
</IconButton>
</Tooltip>
As you can see, this photoURL isn't producing an image, despite in the source code actually being accessed from firebase properly, as can be seen below in the <img> tag (when I right click -> open in new tab, the image is definitely the right one and corresponds to the Google account I used to sign into my web application through Firebase):
To reiterate, the problem isn't accessing the photoURL of the Firebase user, but rather displaying it using either the native <img> or Material UI <Avatar> tag.

Suddenly this works when the only line technically changed was within the <IconButton> (imported from "#mui/material/IconButton") as such:
from sx={{ p: 0 }} to sx={{ px: "15px" }}
This is the final edited code (with the <img> tag removed since it was simply used for testing):
<Tooltip title="Open settings">
<IconButton
onClick={handleOpenUserMenu}
sx={{ px: "15px" }} // only changed line
>
<Avatar
alt="Google Photo/Initial"
src={
auth.currentUser
.photoURL
}
/>
</IconButton>
</Tooltip>
I can only assume that this is what fixed my problem and turned the output into the following:

Related

React, Material UI Menu error MUI: The `anchorEl` prop provided to the component is invalid

I have created MUI Nav bar which has a couple of items on the right. Upon clicking on the user icon a dropdown menu should be displayed. The menu pops up but I get this error -
Warning: Failed prop type: MUI: The `anchorEl` prop provided to the component is invalid. It should be an Element instance but it's `undefined` instead. at Popover (https://inq73y.csb.app/node_modules/#mui/material/Popover/Popover.js:97:43) at eval (https://inq73y.csb.app/node_modules/#emotion/react/dist/emotion-element-b63ca7c6.cjs.dev.js:43:23) at Menu (https://inq73y.csb.app/node_modules/#mui/material/Menu/Menu.js:72:43) at header at eval (https://inq73y.csb.app/node_modules/#emotion/react/dist/emotion-element-b63ca7c6.cjs.dev.js:43:23) at Paper (https://inq73y.csb.app/node_modules/#mui/material/Paper/Paper.js:62:43) at eval (https://inq73y.csb.app/node_modules/#emotion/react/dist/emotion-element-b63ca7c6.cjs.dev.js:43:23) at AppBar (https://inq73y.csb.app/node_modules/#mui/material/AppBar/AppBar.js:107:43) at div at eval (https://inq73y.csb.app/node_modules/#emotion/react/dist/emotion-element-b63ca7c6.cjs.dev.js:43:23) at Box (https://inq73y.csb.app/node_modules/#mui/system/esm/createBox.js:27:40) at ElevationScroll (https://inq73y.csb.app/src/App.js:32:28) at App (https://inq73y.csb.app/src/App.js:43:33)
I have also tried using anchorEl in state and adding it to the menu as described in the MUI docs but in this approach, the menu pops up on the top left instead of right and there is a warning which seems like the same issue to me.
MUI: The `anchorEl` prop provided to the component is invalid. The anchor element should be part of the document layout. Make sure the element is present in the document or that it's not display none. in Transition (created by Grow) in Grow (created by FocusTrap) in FocusTrap (created by ModalUnstyled) in ModalUnstyled (created by Modal) in Modal (created by MuiPopoverRoot) in MuiPopoverRoot (created by Popover) in Popover (created by MuiMenuRoot) in MuiMenuRoot (created by Menu) in Menu (created by App) in App
I have searched a couple of links using refs and getting the nested components out of the parent but I was not able to get those.
This is the link to codesandbox - CodeSandbox
Any help is appreciated. Thanks
The anchorEl property is expecting an element that is always available. The code you have removes this element on close - this is the cause of the error. The expected way to do it is to provide a ref (which is done via the useRef hook) to the element you want to be the anchor and control the visibility of the menu by its open property.
I made some changes to your code and got the error to go away.
const [open, setOpen] = React.useState(false);
const anchorEl = React.useRef();
return (
<>
<ElevationScroll>
<Box sx={{ flexGrow: 1 }}>
<AppBar color="primary" position="fixed">
<Toolbar>
<Box display="flex" alignItems="center">
<Typography>Menu Options </Typography>
</Box>
<Box sx={{ flexGrow: 1 }} />
<Box sx={{ display: { xs: "none", md: "flex" } }}>
<IconButton disableRipple>
<SearchIcon />
</IconButton>
<IconButton disableRipple>
<NotificationsActiveIcon />
</IconButton>
<IconButton
ref={anchorEl}
onClick={() => setOpen(true)}
disableRipple
>
<PersonOutlineOutlined />
</IconButton>
<IconButton disableRipple>
<SettingsOutlined />
</IconButton>
</Box>
</Toolbar>
<Menu
id="menu-appbar"
anchorEl={anchorEl}
anchorOrigin={{
vertical: "top",
horizontal: "right"
}}
keepMounted
transformOrigin={{
vertical: "top",
horizontal: "right"
}}
open={open}
onClose={() => setOpen(false)}
>
<MenuItem>Profile</MenuItem>
<MenuItem>Logout</MenuItem>
</Menu>
</AppBar>
</Box>
</ElevationScroll>
</>
);

How to use Next.js Image component with MaterialUI?

I am able to use the <img> tag no problem, but when I try to use the <Image> component, all that displays is an empty square the size of the image. The only way I have been able to get the image to display without using <img> is with the <Avatar> component. It's just a small brand image so it's not a huge deal, but I would like to use the built-in Next.js image optimization. And using <Avatar> does not feel very semantic as well.
It is being displayed inside of a ListItem component like this:
<Drawer variant="permanent" {...other}>
<List disablePadding>
<ListItem
sx={{
justifyContent: 'center',
alignItems: 'center',
}}
>
<Avatar
src="images/icons/agreement2.png"
alt="Scales of Justice Brand Image"
sx={{ width: 50, height: 50 }}
/>
</ListItem>
This is what I have tried so far:
I created a separate component for the image
import Image from 'next/image'
import brandImage from '../public/images/icons/law.png'
export default function Brand() {
return <Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
}
and displaying <Brand /> inside of the <ListItem> in place of the current <Avatar> component.
I tried to import the .png file and use
<Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
inside of the <ListItem>. And then I tried without importing the image and just using the full file path.
I tried placing <Image> inside of the <Avatar> component.
<Avatar>
<Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
</Avatar>
I also tried adding in the layout prop with all of the options.
I am using Next.js v12.0.9 and MUI v5.4.2
I recommend creating a parent element with a position responsive and setting the image like this:
<Box sx={{position:'relative'}}>
<Image src={brandImage} width="50px" height="50px" alt="Brand Logo" />
</Box>
You also may set it like:
<Box sx={{position:'relative', height:'50px', width:'50px'}}>
<Image src={brandImage} layout="fill" objectFit="cover" alt="Brand Logo" />
</Box>
This seem to work for me.
<Stack
sx={{
height: "500px",
}}
>
<Image
src={image.data.attributes.url}
alt={image.data.attributes.alternativeText}
width={image.data.attributes.width}
height={image.data.attributes.height}
objectFit="cover"
priority
/>
</Stack>
Using Stack seems to expand the image full width without using width: 100%

Content not displayed when using full-screen Dialog in React Material-UI

Following the documentation of material-ui (https://material-ui.com/components/dialogs/),
I see that the dialog can be full screen. However, when I use it with AppBar and ToolBar, the DialogContent does not get displayed.
Below is the code for my dialog.
<Button variant="outlined" color="primary" onClick={handleClickOpen}>
Open full-screen dialog
</Button>
<Dialog fullScreen open={open} onClose={handleClose} TransitionComponent={Transition}>
<AppBar style={{ backgroundColor: "#182026" }} className={classes.appBar}>
<Toolbar>
<IconButton edge="start" color="inherit" onClick={handleClose} aria-label="close">
<CloseIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
Sound
</Typography>
</Toolbar>
</AppBar>
<DialogContent>
<DialogContentText>
Let Google help apps determine location. This means sending anonymous location data to
Google, even when no apps are running.
</DialogContentText>
</DialogContent>
</Dialog>
This just gives me
When I inspect this, I can see that the content is hidden inside the header which is pretty weird.
Since this code is mostly from the demo, I am not sure how to fix it. Thanks in advance.
You need to add position relative to your app bar class.
const useStyles = makeStyles((theme) => ({
appBar: {
position: 'relative',
},
title: {
marginLeft: theme.spacing(2),
flex: 1,
},
}));
And on the actual appear apply
<AppBar className={classes.appBar} />

How do I close a card when onclick on a button in react?

I have a material-ui card in which it contains image, input field, check-box and a submit button. In which card is displaying onclick on some other option which is not mentioned in the below code. I want to close a card when I click on submit. How can I achieve this?
<Card
className="details-card"
style={{ paddingTop: "0px" }}
color="primary"
>
<CardHeader
style={{
paddingBottom: 0,
paddingTop: 0
}}
title="Image"
/>
<img src="https://unsplash.it/200/?random" />
<CardContent className="details-card-body">
<TextField label="Name" fullWidth />
<Grid container>
<Grid item xs={4}>
<Typography>
New User
<Checkbox
checked={this.state.addNew}
name="addNew"
onChange={this.handleCheckBox("addNew")}
value="new user"
inputProps={{ "aria-label": "Checkbox B" }}
/>
</Typography>
</Grid>
</Grid>
<Button variant="contained" color="primary">
Click to Tag
</Button>
</CardContent>
</Card>
Here below is my code on CodeSandbox
https://codesandbox.io/embed/lppzx48r0m
There are multiple ways to achieve what you want to do
you'll need a flag to conditionally hide or show the card.
For example lets take flag variable in state, and change state variable flag based on submit button and on the basis of this.state.flag you can do
{this.state.flag ?
(<Card
className="details-card"
style={{ paddingTop: "0px" }}
color="primary"
>
//Card content
</Card>)
:
null
}
You can also provide conditional css based on this.state.flag
<Card
className="details-card"
style={{ paddingTop: "0px", display: this.state.flag ? block : 'none'}}
color="primary"
>
//Card content
</Card>
P.S.: The second approach is not recommended because we are rendering element even if it is not needed.

Material-UI/React: How to correctly add notification button with Badge to AppBar?

Using material-ui and react/jsx, I have an AppBar. I wanted to add a notifications menu icon with badge (number) on it, that is, to show the number of new notifications.
The problem is that the badge will be displayed incorrectly. That is, with weird styles and look.
Here is what I have already tried
<AppBar>
<IconMenu anchorOrigin={{ horizontal: 'right', vertical: 'top' }}
targetOrigin={{ horizontal: 'right', vertical: 'bottom' }}
iconButtonElement={
<FlatButton label={<Badge badgeContent={5} />} icon={<NotificationsIcon />} />
}
/>
</AppBar>
That way, the badge will not be aligned correctly with the bell (notifications) icon.
I have also tried making the IconMenu part of the AppBar's iconElementRight property to no avail.
Any help?
You're right - it does seem to take some experimenting with the proper nesting order, and even then you have to tweak the style a bit. But, here's a sample webpackbin that I think looks decent without being hacky: http://www.webpackbin.com/EJqz0NVzM
<AppBar>
<IconMenu
iconButtonElement={
<IconButton style={{ padding: 0 }}>
<Badge
badgeStyle={{ top: 12, right: 12, backgroundColor: colors.yellow800 }}
badgeContent={5}
secondary={true}
>
<NotificationIcon color={muiTheme.appBar.textColor} />
</Badge>
</IconButton>
}
>
<MenuItem primaryText="View Notifications" />
<MenuItem primaryText="Dismiss All" />
</IconMenu>
</AppBar>
Once you nest the components correctly, the final bit is setting the padding on the IconButton to zero. Once you do this, it will look as expected according to the material-ui docs.
In this configuration, in my humble opinion, the badge is floating a little too far away from the notification icon. So, I also added a custom "badgeStyle" to nudge the badge inward to overlay on top of the notification icon slightly. I also put a custom yellow color on the badge too, just to illustrate that you can further customize the look of that badge (could change borderRadius, boxShadow, fontSize, etc)

Resources