Can't get image to preview in React? - javascript

I'm writing a social media app that allows you to post either text or image posts. I'm struggling to be able to show image as preview when posting.
It doesn't seem to be able to set the imageData, or does so async and idk how to await the result so it shows in my preview.
Heres the parent component:
import React, { useState } from "react";
import { collection, addDoc, getFirestore } from "firebase/firestore";
import { useUserContext } from "../../../services/user-context";
import { getStorage, ref, uploadBytes } from "firebase/storage";
import TextPost from "./TextPost";
import ImagePost from "./ImagePost";
export const CreatePostModal = ({ open, setOpen }) => {
const { user } = useUserContext();
const db = getFirestore();
const storage = getStorage();
const [imageData, setImageData] = useState(null);
const handleImageUpload = async (e) => {
if (e.target.files[0]) {
const reader = new FileReader();
reader.onload = (img) => setImageData(img.target.result);
reader.readAsDataURL(await e.target.files[0]);
console.log(imageData);
}
};
const pictureUploadRef = ref(storage, "posts/");
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
console.log(formData);
const title = formData.get("title");
const content = formData.get("content");
const postRef = await addDoc(collection(db, "posts"), {
comments: [],
content: content,
likes: [],
picture: imageData,
technologies: [],
timestamp: new Date(),
title: title,
userAvatar: "avatarUrl",
userID: user.id,
});
};
return imageData ? (
<div>
<ImagePost
open={open}
setOpen={setOpen}
handleImageUpload={handleImageUpload}
handleSubmit={handleSubmit}
/>
</div>
) : (
<div>
<TextPost
open={open}
setOpen={setOpen}
handleImageUpload={handleImageUpload}
handleSubmit={handleSubmit}
imageData={imageData}
/>
</div>
);
};
And here is child:
import React from "react";
import Box from "#mui/material/Box";
import Typography from "#mui/material/Typography";
import Modal from "#mui/material/Modal";
import styled from "styled-components";
import { Button } from "#mui/material";
import ImageIcon from "#mui/icons-material/Image";
const TitleInput = styled.textarea`
width: 100%;
height: 10%;
border: none;
background-color: inherit;
font-size: 25px;
resize: none;
&:focus-visible {
outline: none;
}
&::placeholder {
color: black;
}
text-align: center;
margin: 10px 0 15px;
color: black;
`;
const ContentInput = styled.textarea`
width: 100%;
height: 20%;
border: none;
background-color: inherit;
font-size: 20px;
resize: none;
&:focus-visible {
outline: none;
}
&::placeholder {
color: black;
}
`;
const ImageContainer = styled.div`
width: 100%;
height: 50%;
// background-color: red;
`;
const style = {
position: "absolute",
height: "50%",
minWidth: "400px",
minHeight: "550px",
width: "40%",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
bgcolor: "#f0f2f5",
boxShadow: 24,
p: 4,
borderRadius: "20px",
display: "flex",
justifyContent: "flex-start",
alignItems: "center",
flexDirection: "column",
outline: "none",
padding: "15px 25px 25px",
};
const ImagePost = ({
open,
setOpen,
handleImageUpload,
handleSubmit,
imageData,
}) => {
return (
<Modal
open={open}
onClose={() => setOpen(false)}
aria-labelledby="modal-modal-title"
>
<Box sx={style}>
<Typography
id="modal-modal-title"
variant="h4"
component="h2"
sx={{ fontSize: "30px" }}
>
Create a post
</Typography>
<div
style={{
border: "0.5px solid #a6a6a6",
width: "100%",
margin: "15px 0 0",
}}
/>
<form style={{ width: "100%", height: "100%" }}>
<TitleInput placeholder="Post title" required name="title" />
<ContentInput placeholder="Post content" required name="content" />
<ImageContainer>
{imageData ? <img src={imageData} alt="" /> : <p>failed</p>}
</ImageContainer>
<div style={{ display: "flex", justifyContent: "center" }}>
<label htmlFor="upload-button">
<input
onChange={handleImageUpload}
accept="image/*"
id="upload-button"
type="file"
style={{ display: "none" }}
/>
<Button
variant="contained"
size="large"
sx={{ ml: "-70px" }}
component="span"
>
<ImageIcon />
</Button>
</label>
<label htmlFor="submit-button">
<Button
type="submit"
id="submit-button"
variant="contained"
size="large"
color="success"
sx={{ ml: "10px", width: "150px" }}
onClick={handleSubmit}
>
Submit
</Button>
</label>
</div>
</form>
</Box>
</Modal>
);
};
export default ImagePost;
Can you help me figure out what I'm doing wrong?

1 key thing that you are missing here is that react state updates are not instantaneous, they are scheduled. You make api call which is async and may complete after the page has already been rendered. you may wanna look into useEffect hook to solve this problem.

Related

How to place any button outside the dialog box

I want a close button that needs to work outside the dialog box.
I want this modal where the close button is outside div.
Expected:
Implementation:
const Component = styled(Box)`
display: flex;
height: 528px;
`;
const Image = styled(Box)`
width: 270px;
background: url(https://static-assets-web.flixcart.com/www/linchpin/fk-cp-zion/img/login_img_c4a81e.png)
no-repeat;
color: #fff;
background-color: #2874f0;
background-position: 50% 85%;
padding: 40px 33px;
& > p {
margin-top: 12px;
color: #dbdbdb;
font-size: 18px;
}
`;
const ReqBtn = styled(Button)`
background-color: #fb641b;
text-transform: none;
height: 48px;
width: 305px;
padding: 10px 20px 10px 20px;
`;
const Wrapper = styled(Box)`
padding: 56px 35px 16px 35px;
& > p {
color: #878787;
font-size: 12px;
}
`;
// <--------------------------------------- styled section ends-------------------------------->
const LoginDialog = ({ open, setOpen }) => {
const handleCloseDialog = () => {
setOpen(false);
};
return (
<Dialog
open={open}
onClose={handleCloseDialog}
sx={{
"& .MuiDialog-container": {
"& .MuiPaper-root": {
width: "100%",
maxWidth: "750px",
},
},
}}
>
<Component>
<Image>
{/* <Typography
style={{ fontWeight: "bold", fontSize: "28px", color: "#fff" }}
>
Login
</Typography>
<Typography>
Get access to your Orders, Wishlist and Recommendations
</Typography> */}
</Image>
<Wrapper>
{/* <TextField label="Enter Email/Mobile Number" variant="standard" />
<Typography>
By continuing, you agree to Flipkart's Terms of Use and Privacy
Policy.
</Typography>
<ReqBtn
variant="contained"
sx={{
"&.MuiButtonBase-root:hover": { backgroundColor: "#fb641b" },
}}
>
Request OTP
</ReqBtn>
<Typography>New to Flipkart?Create an Account</Typography> */}
</Wrapper>
//close button
<ClearIcon
onClick={handleCloseDialog}
style={{ cursor: "pointer", backgroundColor: "yellow" }}
/>
</Component>
</Dialog>
);
};
export default LoginDialog;
I tried pasting the <ClearICon> outside <Dialog> component but the issue is the close button came in my navbar position
<>
<ClearIcon
onClick={handleCloseDialog}
style={{ cursor: "pointer", backgroundColor: "yellow" }}
/>
</>
How can I place the CloseIcon outside the dialog box as per provided design?
something like this...
.box{
position:relative;
background:gray;
width:100px;
height:100px;
}
.box>.controls{
position:absolute;
right:-30px;
}
<div class="box">
<div class="controls">
<button>x</button>
</div>
</div>

Text area keeps losing focus

I change the post button from an icon to text, when message is written. But my input keeps losing focus and I have to click it to type each letter. I have commented the code which is causing the problem (in my oppinion). I have been trying to solve it. I moved the textarea out of the component, I gave it a unique key, I moved the Post button out to a new component but none of it worked. Please help!
My Code:
import { useState, useRef, useEffect } from "react"
import {
Box,
Typography,
Button
} from "#mui/material"
import { styled } from "#mui/system"
import {
InfoOutlined as InfoIcon,
InsertPhotoOutlined as PhotoIcon
} from "#mui/icons-material"
import Message from "./Message"
import EmojiPicker from "../EmojiPicker/EmojiPicker"
const Chat = () => {
const Container = styled(Box)({
width: '100%',
display: 'flex',
flexDirection: 'column',
flex: 1
})
const HeaderContainer = styled(Box)({
display: 'flex',
justifyContent: 'space-between',
alignItems: 'center',
padding: '1.2rem 2rem',
borderBottom: '1px solid #e8e8e8',
borderLeft: '1px solid #e8e8e8'
})
const NameContainer = styled(Box)({
display: 'flex',
alignItems: 'center',
cursor: 'pointer'
})
const ImageContainer = styled(Box)({
width: '30px',
height: '30px',
borderRadius: '50%',
overflow: 'hidden'
})
const ProfileName = styled(Typography)({
fontSize: '1.7rem',
fontWeight: '600',
marginLeft: '1.5rem'
})
const imageStyles = {
width: '100%',
height: '100%',
objectFit: 'cover',
objectPosition: 'center'
}
const ChatContainer = styled(Box)({
flex: 1,
display: 'flex',
flexDirection: 'column',
overflowY: 'scroll',
padding: '1.5rem'
})
const MessageFieldContainer = styled(Box)({
display: 'flex',
alignItems: 'center',
padding: '.5rem 1rem',
border: '1px solid #8e8e8e',
borderRadius: '25px'
})
const SendButton = styled(Button)({
fontWeight: '600',
fontSize: '1.3rem',
textTransform: 'none',
padding: '0'
})
const messageFieldStyles = {
border: 'none',
outline: 'none',
fontSize: '1.4rem',
fontFamily: 'inherit',
resize: 'none',
flex: 1
}
const [message, setMessage] = useState('')
return (
<Container>
<HeaderContainer>
<NameContainer>
<ImageContainer>
<img style={imageStyles} component="image" src="images/person.jpg"/>
</ImageContainer>
<ProfileName>Asfand Yar</ProfileName>
</NameContainer>
<InfoIcon sx={{
fontSize: '2.5rem',
cursor: 'pointer'
}}/>
</HeaderContainer>
<ChatContainer>
<Message type="reciever">Hello</Message>
</ChatContainer>
<Box sx={{ padding: '2rem' }}>
<MessageFieldContainer>
<EmojiPicker />
// Error Code ***********
<textarea
placeholder="Message..."
name="message"
rows="1"
style={messageFieldStyles}
value={message}
onChange={(e) => setMessage(e.target.value)}/>
{
message == "" ? <PhotoIcon sx={{ fontSize: '2.5rem'}}/> : <SendButton>Send</SendButton>
}
// ***************
</MessageFieldContainer>
</Box>
</Container>
)
}
export default Chat

How do I make two different screens look like doing a one variable check in css and html? (look below)

i am creating a website for my nft collection, with a whitelist sale and a public sale. My problem, once the user is logged in with his metamask account, he should put a check if his wallet is whitelisted. If your wallet belongs to the whitelist, then it appears as a screen and you can proceed with the purchase of the NFT, if your wallet does not belong to the whitelist you will have another screen that you have to pass to buy the NFT. Can someone help me?
import React, { useEffect, useState, useRef } from "react";
import { useDispatch, useSelector } from "react-redux";
import { connect } from "./redux/blockchain/blockchainActions";
import { fetchData } from "./redux/data/dataActions";
import * as s from "./styles/globalStyles";
import styled from "styled-components";
const truncate = (input, len) =>
input.length > len ? `${input.substring(0, len)}...` : input;
const whitelistedAddresses = ['here the first address', 'here the second address'];
const whitelisted = "Congratulations, you are whitelisted!";
const notWhitelisted = "You are not whitelisted";
export const StyledButton = styled.button`
padding: 10px;
border-radius: 50px;
border: none;
background-color: var(--secondary);
padding: 10px;
font-weight: bold;
color: var(--secondary-text);
width: 100px;
cursor: pointer;
box-shadow: 0px 6px 0px -2px rgba(250, 250, 250, 0.3);
-webkit-box-shadow: 0px 6px 0px -2px rgba(250, 250, 250, 0.3);
-moz-box-shadow: 0px 6px 0px -2px rgba(250, 250, 250, 0.3);
:active {
box-shadow: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
}
`;
export const StyledRoundButton = styled.button`
padding: 10px;
border-radius: 100%;
border: none;
background-color: var(--primary);
padding: 10px;
font-weight: bold;
font-size: 15px;
color: var(--primary-text);
width: 30px;
height: 30px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0px 4px 0px -2px rgba(250, 250, 250, 0.3);
-webkit-box-shadow: 0px 4px 0px -2px rgba(250, 250, 250, 0.3);
-moz-box-shadow: 0px 4px 0px -2px rgba(250, 250, 250, 0.3);
:active {
box-shadow: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
}
`;
export const ResponsiveWrapper = styled.div`
display: flex;
flex: 1;
flex-direction: column;
justify-content: stretched;
align-items: stretched;
width: 100%;
#media (min-width: 767px) {
flex-direction: row;
}
`;
export const StyledLogo = styled.img`
width: 200px;
#media (min-width: 767px) {
width: 300px;
}
transition: width 0.5s;
transition: height 0.5s;
`;
export const StyledImg = styled.img`
box-shadow: 0px 5px 11px 2px rgba(0, 0, 0, 0.7);
border: 4px dashed var(--secondary);
background-color: var(--accent);
border-radius: 100%;
width: 200px;
#media (min-width: 900px) {
width: 250px;
}
#media (min-width: 1000px) {
width: 300px;
}
transition: width 0.5s;
`;
export const StyledLink = styled.a`
color: var(--secondary);
text-decoration: none;
`;
function App() {
const whitelistedAddresses = ['0x74be05EDACC9c0CcEb78BC0fCB76315069b6F411', '0x7490ED764e113F9283507E8401b011c8eF8F2Dbe'];
const dispatch = useDispatch();
const blockchain = useSelector((state) => state.blockchain);
const data = useSelector((state) => state.data);
const [claimingNft, setClaimingNft] = useState(false);
const [feedback, setFeedback] = useState(`Click buy to mint your NFT.`);
const [mintAmount, setMintAmount] = useState(1);
const [CONFIG, SET_CONFIG] = useState({
CONTRACT_ADDRESS: "",
SCAN_LINK: "",
NETWORK: {
NAME: "",
SYMBOL: "",
ID: 4,
},
NFT_NAME: "",
SYMBOL: "",
MAX_SUPPLY: 1,
WEI_FREE_MINT_COST: 0,
DISPLAY_FREE_MINT_COST: 0,
WEI_PUBLIC_COST: 0,
DISPLAY_PUBLIC_COST: 0,
GAS_LIMIT: 0,
MARKETPLACE: "",
MARKETPLACE_LINK: "",
SHOW_BACKGROUND: false,
});
const FreeMint = () => {
let freeMintCost = CONFIG.WEI_FREE_MINT_COST;
let gasLimit = CONFIG.GAS_LIMIT;
let totalFreeMintCostWei = String(freeMintCost * mintAmount);
let totalGasLimit = String(gasLimit * mintAmount);
console.log("Cost: ", totalFreeMintCostWei);
console.log("Gas limit: ", totalGasLimit);
setFeedback(`Minting your ${CONFIG.NFT_NAME}...`);
setClaimingNft(true);
blockchain.smartContract.methods
.freeMint(mintAmount)
.send({
gasLimit: String(totalGasLimit),
to: CONFIG.CONTRACT_ADDRESS,
from: blockchain.account,
value: totalFreeMintCostWei,
})
.once("error", (err) => {
console.log(err);
setFeedback("Sorry, something went wrong please try again later.");
setClaimingNft(false);
})
.then((receipt) => {
console.log(receipt);
setFeedback(
`WOW, the ${CONFIG.NFT_NAME} is yours! go visit Opensea.io to view it.`
);
setClaimingNft(false);
dispatch(fetchData(blockchain.account));
});
};
const claimNFTs = () => {
let publicCost = CONFIG.WEI_PUBLIC_COST;
let gasLimit = CONFIG.GAS_LIMIT;
let totalPublicCostWei = String(publicCost * mintAmount);
let totalGasLimit = String(gasLimit * mintAmount);
console.log("Cost: ", totalPublicCostWei);
console.log("Gas limit: ", totalGasLimit);
setFeedback(`Minting your ${CONFIG.NFT_NAME}...`);
setClaimingNft(true);
blockchain.smartContract.methods
.mint(mintAmount)
.send({
gasLimit: String(totalGasLimit),
to: CONFIG.CONTRACT_ADDRESS,
from: blockchain.account,
value: totalPublicCostWei,
})
.once("error", (err) => {
console.log(err);
setFeedback("Sorry, something went wrong please try again later.");
setClaimingNft(false);
})
.then((receipt) => {
console.log(receipt);
setFeedback(
`WOW, the ${CONFIG.NFT_NAME} is yours! go visit Opensea.io to view it.`
);
setClaimingNft(false);
dispatch(fetchData(blockchain.account));
});
};
const decrementMintAmount = () => {
let newMintAmount = mintAmount - 1;
if (newMintAmount < 1) {
newMintAmount = 1;
}
setMintAmount(newMintAmount);
};
const incrementMintAmount = () => {
let newMintAmount = mintAmount + 1;
if (newMintAmount > 10) {
newMintAmount = 10;
}
setMintAmount(newMintAmount);
};
const getData = () => {
if (blockchain.account !== "" && blockchain.smartContract !== null) {
dispatch(fetchData(blockchain.account));
}
};
const getConfig = async () => {
const configResponse = await fetch("/config/config.json", {
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
});
const config = await configResponse.json();
SET_CONFIG(config);
};
useEffect(() => {
getConfig();
}, []);
useEffect(() => {
getData();
}, [blockchain.account]);
return (
<s.Screen>
<s.Container
flex={1}
ai={"center"}
style={{ padding: 24, backgroundColor: "var(--primary)" }}
image={CONFIG.SHOW_BACKGROUND ? "/config/images/bg.png" : null}
>
<StyledLogo alt={"logo"} src={"/config/images/logo.png"} />
<s.SpacerSmall />
<ResponsiveWrapper flex={1} style={{ padding: 24 }} test>
<s.Container flex={1} jc={"center"} ai={"center"}>
<StyledImg alt={"example"} src={"/config/images/example.gif"} />
</s.Container>
<s.SpacerLarge />
<s.Container
flex={2}
jc={"center"}
ai={"center"}
style={{
backgroundColor: "var(--accent)",
padding: 24,
borderRadius: 24,
border: "4px dashed var(--secondary)",
boxShadow: "0px 5px 11px 2px rgba(0,0,0,0.7)",
}}
>
<s.TextTitle
style={{
textAlign: "center",
fontSize: 50,
fontWeight: "bold",
color: "var(--accent-text)",
}}
>
{data.totalSupply} / {CONFIG.MAX_SUPPLY}
</s.TextTitle>
<s.TextDescription
style={{
textAlign: "center",
color: "var(--primary-text)",
}}
>
<StyledLink target={"_blank"} href={CONFIG.SCAN_LINK}>
{truncate(CONFIG.CONTRACT_ADDRESS, 50)}
</StyledLink>
</s.TextDescription>
<s.SpacerSmall />
{Number(data.totalSupply) >= CONFIG.MAX_SUPPLY ? (
<>
<s.TextTitle
style={{ textAlign: "center", color: "var(--accent-text)" }}
>
The sale has ended.
</s.TextTitle>
<s.TextDescription
style={{ textAlign: "center", color: "var(--accent-text)" }}
>
You can still find {CONFIG.NFT_NAME} on
</s.TextDescription>
<s.SpacerSmall />
<StyledLink target={"_blank"} href={CONFIG.MARKETPLACE_LINK}>
{CONFIG.MARKETPLACE}
</StyledLink>
</>
) : (
<>
<s.TextTitle
style={{ textAlign: "center", color: "var(--accent-text)" }}
>
1 {CONFIG.SYMBOL} costs {CONFIG.DISPLAY_COST}{" "}
{CONFIG.NETWORK.SYMBOL}.
</s.TextTitle>
<s.SpacerXSmall />
<s.TextDescription
style={{ textAlign: "center", color: "var(--accent-text)" }}
>
Excluding gas fees.
{feedback}
</s.TextDescription>
<s.SpacerSmall />
{blockchain.account === "" ||
blockchain.smartContract === null ? (
<s.Container ai={"center"} jc={"center"}>
<s.TextDescription
style={{
textAlign: "center",
color: "var(--accent-text)",
}}
>
Connect to the {CONFIG.NETWORK.NAME} network
</s.TextDescription>
<s.SpacerSmall />
<StyledButton
onClick={(e) => {
e.preventDefault();
dispatch(connect());
getData();
}}
>
CONNECT
</StyledButton>
{blockchain.errorMsg !== "" ? (
<>
<s.SpacerSmall />
<s.TextDescription
style={{
textAlign: "center",
color: "var(--accent-text)",
}}
>
{blockchain.errorMsg}
</s.TextDescription>
</>
) : null}
</s.Container>
) : (
<>
<s.TextDescription
style={{
textAlign: "center",
color: "var(--accent-text)",
}}
>
</s.TextDescription>
<s.SpacerMedium />
<s.Container ai={"center"} jc={"center"} fd={"row"}>
<StyledRoundButton
style={{ lineHeight: 0.4 }}
disabled={claimingNft ? 1 : 0}
onClick={(e) => {
e.preventDefault();
decrementMintAmount();
}}
>
-
</StyledRoundButton>
<s.SpacerMedium />
<s.TextDescription
style={{
textAlign: "center",
color: "var(--accent-text)",
}}
>
{mintAmount}
</s.TextDescription>
<s.SpacerMedium />
<StyledRoundButton
disabled={claimingNft ? 1 : 0}
onClick={(e) => {
e.preventDefault();
incrementMintAmount();
}}
>
+
</StyledRoundButton>
</s.Container>
<s.SpacerSmall />
<s.Container ai={"center"} jc={"center"} fd={"row"}>
<StyledButton
disabled={claimingNft ? 1 : 0}
onClick={(e) => {
e.preventDefault();
FreeMint();
getData();
}}
>
{claimingNft ? "BUSY" : "BUY"}
</StyledButton>
</s.Container>
</>
)}
</>
)}
<s.SpacerMedium />
</s.Container>
<s.SpacerLarge />
<s.Container flex={1} jc={"center"} ai={"center"}>
<StyledImg
alt={"example"}
src={"/config/images/example.gif"}
style={{ transform: "scaleX(-1)" }}
/>
</s.Container>
</ResponsiveWrapper>
<s.SpacerMedium />
<s.Container jc={"center"} ai={"center"} style={{ width: "70%" }}>
<s.TextDescription
style={{
textAlign: "center",
color: "var(--primary-text)",
}}
>
Please make sure you are connected to the right network (
{CONFIG.NETWORK.NAME} Mainnet) and the correct address. Please note:
Once you make the purchase, you cannot undo this action.
</s.TextDescription>
<s.SpacerSmall />
<s.TextDescription
style={{
textAlign: "center",
color: "var(--primary-text)",
}}
>
We have set the gas limit to {CONFIG.GAS_LIMIT} for the contract to
successfully mint your NFT. We recommend that you don't lower the
gas limit.
</s.TextDescription>
</s.Container>
</s.Container>
</s.Screen>
);
}
export default App;

Give each Popper its own css style

I have a componet that creates 6 experiences each one with its own popper. I want to edit the popper's so that each popper has its each style (background and possition) and I want them all to have the same size image.
I have tried edditing the paper style and adding a className with the id of each experience as the className property but cannot get any styles I apply to work.
This is my experience compoenent.
import React, { memo, useCallback } from 'react';
import PropTypes from 'prop-types';
import { makeStyles } from '#material-ui/styles';
import Grid from '#material-ui/core/Grid';
import Typography from '#material-ui/core/Typography';
import clsx from 'clsx';
import Popper from '#material-ui/core/Popper';
import gastronomia from 'assets/experiences/gastronomia.jpg';
import productos from 'assets/experiences/productos.jpg';
import giftcard from 'assets/experiences/giftcard.jpg';
import diversion from 'assets/experiences/diversion.jpg';
import deporte from 'assets/experiences/deporte.jpg';
import belleza from 'assets/experiences/belleza.jpg';
import gastronomiaExperiences from 'data/gastronomia';
import productosExperiences from 'data/productos';
import giftcardExperiences from 'data/giftcard';
import diversionExperiences from 'data/diversion';
import deporteExperiences from 'data/deporte';
import bellezaExperiences from 'data/belleza';
// Proptypes definitions to the component.
const propTypes = {
/** Custom root className. */
className: PropTypes.string,
};
// Default props definitions.
const defaultProps = {
className: null,
};
// Component's styles
const useStyles = makeStyles(theme => ({
root: {
display: 'block',
margin: '0 auto',
maxWidth: '50%',
[theme.breakpoints.down('md')]: {
maxWidth: '70%',
},
[theme.breakpoints.down('sm')]: {
maxWidth: '100%',
},
'& .experiences-column': {
display: 'inline-block',
verticalAlign: 'top',
textAlign: 'center',
'&.col1': {
width: '36.31%',
[theme.breakpoints.down('sm')]: {
width: 'initial',
},
},
'&.col2': {
width: '63.69%',
[theme.breakpoints.down('sm')]: {
width: 'initial',
},
},
'& .experience': {
padding: 2,
position: 'relative',
'& img': {
width: '100%',
display: 'block',
},
'& .experience-title': {
position: 'absolute',
bottom: 30,
left: 0,
right: 0,
textAlign: 'center',
},
'& .deporte': {
backgroundColor: '#000',
'& img': {
width: '30px',
display: 'block',
},
},
},
paper: {
border: '1px solid',
padding: theme.spacing(1)
},
},
},
}), { name: 'ExperiencesStyle' });
/**
* Component used to render a grid of experiences.
*
* #param {object} props - The component's props.
* #returns {object} React element.
*/
const Experiences = memo(
(props) => {
const { className } = props;
const classes = useStyles(props);
const [anchorEl, setAnchorEl] = React.useState(null);
const handleClick = (event) => {
setAnchorEl(event.currentTarget);
};
const open = Boolean(anchorEl);
const experience = (img, title, id, popoverCategory) => (
<div
className="experience"
aria-describedby={id}
id={id}
onClick={handleClick}
>
<img
data-sizes="auto"
className="lazyload"
data-src={img}
alt={title}
/>
<div className="experience-title">
<Typography
color="textSecondary"
variant="subtitle2"
className="highlight highlight1"
display="inline"
>
{ title }
</Typography>
</div>
<Popper
id={id}
open={anchorEl && anchorEl.id === id || false}
anchorEl={anchorEl}
className={id}
>
<div className={[classes.paper, id]}>
{
popoverCategory.map(url => (
<Grid
sm={4}
>
<img
key={id}
data-sizes="auto"
className="lazyload"
src={url}
alt={ title }
/>
</Grid>
))
}
</div>
</Popper>
</div>
);
console.log();
return (
<div className={clsx(classes.root, className)}>
<div className="experiences-column col1">
{experience(gastronomia, 'GASTRONOMÍA', 'gastronomia', gastronomiaExperiences)}
{experience(giftcard, 'GIFT CARD', 'giftcard', giftcardExperiences)}
{experience(deporte, 'DEPORTE', 'deporte', deporteExperiences)}
</div>
<div className="experiences-column col2">
{experience(productos, 'PRODUCTOS', 'productos', productosExperiences)}
{experience(diversion, 'DIVERSIÓN', 'diversion', diversionExperiences)}
{experience(belleza, 'BELLEZA', 'belleza', bellezaExperiences)}
</div>
</div>
);
},
);
// Component proptypes.
Experiences.propTypes = propTypes;
// Component default props.
Experiences.defaultProps = defaultProps;
export default Experiences;
I am new to meterial ui and relatively new to react so I am a bit lost on how to get the styles to work.
The following code only applies when there is the deporte class is inside a paper class.
paper: {
border: '1px solid',
padding: theme.spacing(1)},
'& .deporte': {
backgroundColor: '#000',
'& img': {
width: '30px',
display: 'block',
},
},
You can take it out of the paper component in the style and put it in the root.
const useStyles = makeStyles(theme => ({
root: {
display: 'block',
margin: '0 auto',
maxWidth: '50%',
[theme.breakpoints.down('md')]: {
maxWidth: '70%',
},
[theme.breakpoints.down('sm')]: {
maxWidth: '100%',
},
'& .experiences-column': {
display: 'inline-block',
verticalAlign: 'top',
textAlign: 'center',
'&.col1': {
width: '36.31%',
[theme.breakpoints.down('sm')]: {
width: 'initial',
},
},
'&.col2': {
width: '63.69%',
[theme.breakpoints.down('sm')]: {
width: 'initial',
},
},
'& .experience': {
padding: 2,
position: 'relative',
'& img': {
width: '100%',
display: 'block',
},
'& .experience-title': {
position: 'absolute',
bottom: 30,
left: 0,
right: 0,
textAlign: 'center',
},
},
},
},
deporte: {
backgroundColor: '#000',
'& img': {
width: '30px',
display: 'block',
},
},
paper: {
border: '1px solid',
padding: theme.spacing(1),
},
}), { name: 'ExperiencesStyle' });
Also replace this:
<Popper
id={id}
open={anchorEl && anchorEl.id === id || false}
anchorEl={anchorEl}
className={id}
>
<div className={classes.paper}>
{
popoverCategory.map(url => (
<Grid
sm={4}
>
<img
key={id}
data-sizes="auto"
className="lazyload"
src={url}
alt={ title }
/>
</Grid>
))
}
</div>
</Popper>
with this:
<Popper
id={id}
open={anchorEl && anchorEl.id === id || false}
anchorEl={anchorEl}
className={id}
>
<div className={clsx(classes.paper, classes[id])}>
{
popoverCategory.map(url => (
<Grid
sm={4}
>
<img
key={id}
data-sizes="auto"
className="lazyload"
src={url}
alt={ title }
/>
</Grid>
))
}
</div>
</Popper>

Styling help: Transparent appbar with Material UI in React.js

I am using material ui and i have been trying to make the navabr transparent and get the background image behind it, a similar style to stripe.com and i am having trouble moving the image behind and getting it transparent.
Is there a way to get it looking like stripe.com with the transparent appbar and background image moved up? The main problem is moving up the background image
Code for the Navbar
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '#material-ui/core/styles';
import AppBar from '#material-ui/core/AppBar';
import Toolbar from '#material-ui/core/Toolbar';
import Typography from '#material-ui/core/Typography';
import Button from '#material-ui/core/Button';
import IconButton from '#material-ui/core/IconButton';
import Dialog from '#material-ui/core/Dialog';
import DialogActions from '#material-ui/core/DialogActions';
import DialogContent from '#material-ui/core/DialogContent';
import DialogContentText from '#material-ui/core/DialogContentText';
import DialogTitle from '#material-ui/core/DialogTitle';
import Checkbox from '#material-ui/core/Checkbox';
import TextField from '#material-ui/core/TextField';
import { Link } from 'react-router-dom'
// Styling for our navbar
const styles = {
root: {
flexGrow: 1,
},
grow: {
flexGrow: 1,
},
menuButton: {
marginLeft: -12,
marginRight: 20,
},
button: {
margin: 10,
fontSize: 17
},
text: {
textAlign: 'center',
fontSize: 20,
padding: '0.5em'
},
textField: {
align: 'center',
width: 500
}
};
const MyLink = props => <Link to="/signup" {...props} />
// here is our navbar
class Navbar extends React.Component{
state = {
open: false,
};
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false });
};
state = {
checkedA: true,
checkedB: true,
checkedF: true,
};
handleChange = name => event => {
this.setState({ [name]: event.target.checked });
};
render(){
const { classes } = this.props
return (
<div className={classes.root}>
<AppBar position="static" color="inherit" style={{ background: 'transparent', boxShadow: 'none'}}>
<Toolbar>
<IconButton className={classes.menuButton} color="inherit" aria-label="Menu">
</IconButton>
<Typography variant="h6" color="inherit" className={classes.grow}>
</Typography>
<Button color="inherit" onClick={this.handleClickOpen}>Login</Button>
</Toolbar>
</AppBar>
<Dialog
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description">
<DialogTitle id="alert-dialog-title">{"Have an account? Log In"}</DialogTitle>
<DialogContent>
<DialogTitle>
<Button variant="contained" color="primary" className={classes.button}>
Sign In with Facebook </Button>
<Button variant="contained" color="primary" className={classes.button}>
Sign In with LinkedIn </Button>
</DialogTitle>
<DialogContentText className={classes.text}>
or
</DialogContentText>
<form>
<TextField
id="filled-email-input"
label="Email"
className={classes.textField}
type="email"
name="email"
autoComplete="email"
margin="normal"
variant="filled"
/>
</form>
<form>
<TextField
id="filled-password-input"
label="Password"
className={classes.textField}
type="password"
autoComplete="current-password"
margin="normal"
variant="filled"
/>
</form>
<Checkbox
checked={this.state.checkedG}
onChange={this.handleChange('checkedG')}
value="checkedG"
color= "inherit"
/>
<DialogContentText>
Remember Me?
</DialogContentText>
</DialogContent>
<DialogActions>
<Button component={MyLink} color="primary" autoFocus>
Don't have an account? Sign Up
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
// requiring a class object
Navbar.propTypes = {
classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(Navbar);
And heres the code for the Lading page header/background
import React, {Component} from 'react';
import Background from '../img/fixedImg.png';
import './Header.css';
import { Link } from 'react-router-dom';
const headerStyle = {
backgroundImage: `url( ${Background} )`,
height: '100vh',
backgroundSize: 'cover'
}
// class component for our image on the home page
// the <br> needs fixing in the css file
class Header extends Component {
render() {
return (
<header style={headerStyle}>
<h1>Hashtag Hound </h1>
<p> Connecting influencers with brands </p>
<Link to="/signup">Find an Influencer</Link>
</header>
);
}
};
export default Header;
Here is the css for it
header {
margin: 0 auto;
text-align: center;
}
header h1 {
margin: 0;
font-family: arial;
font-size: 4rem;
color: #383636;
}
header p {
font-weight: 700;
font-size: 1.75rem;
font-family: arial;
color: #383636;
}
header a {
box-shadow: 0 3px 3px 0 rgb(0,0,0,1);
font-weight: 700;
font-size: 1.2rem;
background-color: black;
border-color: black;
color: white;
padding: 1.25rem 2.5rem;
border-radius: 2rem;
text-decoration: none;
font-family: arial;
display: inline-block;
}

Categories