How to import just one function from different file into other? - reactjs

I have a layout file where I made footer and navigation and I insert these two functions in Layout const (code below). In the new file, I just need the Navigation function so how I can insert it without a footer? Because when I write in my new file import Navigation from "../components/layout" and the in code insert I've got error...
const Layout = ({ children }) => {return (
<div>
<Navigation></Navigation>
<Global
styles={{
html: {
backgroundColor: "#fff",
color: "#111",
fontFamily: `'Poppins', sans-serif`,
fontSize: 14,
[Screen.S]: {
fontSize: 16,
},
[Screen.M]: {
fontSize: 18,
},
[Screen.L]: {
fontSize: 20,
},
},
a: {
color: "unset",
},
}}
/>
{children}
<Footer></Footer>
</div>
)
}
function Navigation() { const [navbarOpen, setNavbarOpen] = useState(false) return (
<header
css={{
width: "100%",
maxWidth: "100%",
padding: "0 24px",
position: "fixed",
background: "#fff",
boxShadow: "0 0 0.35rem rgba(0,0,0,.25)",
zIndex: "100",
top: 0,
}}
>
<div
css={{
gridAutoFlow: "column",
minHeight: "4.5rem",
display: "grid",
maxWidth: 1200,
margin: "0 auto",
gridTemplateColumns: "auto 1fr",
alignItems: "center",
paddingLeft: 35,
}}>
<Link to="/ ">
<img style={{ height: "2.5rem" }} src={logo}/>
</Link>
<Toggle
navbarOpen={navbarOpen}
onClick={() => setNavbarOpen(!navbarOpen)}
>
{navbarOpen ? <Hamburger open /> : <Hamburger />}
</Toggle>
{navbarOpen ? (
<NavBoxIcons>
<NavbarSocialLinks />
</NavBoxIcons>
) : (
<NavBox open>
<div>
<HeaderLink>About</HeaderLink>
<HeaderLink>Blog</HeaderLink>
</div>
<div>
<NavbarLinks />
</div>
</NavBox>
)
}
</div>
</header >
)
}
function Footer() { return (
<footer
css={{
padding: "6rem 2rem",
fontSize: "1rem",
minHeight: 160,
fontFamily: "sans-serif",
...Css.container,
}}
>
<div
css={{
display: "flex",
flexDirection: "column",
marginBottom: "3.6rem",
}}
>
<div
css={{
fontSize: "1.2rem",
display: "grid",
gridGap: "0.8rem",
}}>
<a>
<span>Privacy police</span>
</a>
</div>
</div>
<div
css={{
display: "grid",
gridTemplateColumns: "1fr auto",
alignItems: "center",
fontWeight: "lighter",
}}>
<div css={{ display: "flex", flexDirection: "column" }}>
<span>My Page</span>
</div>
</div>
</footer>
)
}

try exporting both Navigation and Footer like this
//at bottom of file
export {Navigation, Footer}
import individual component like this
import {Navigation} from 'components/layout'
or
import {Navigation,Footer} from 'components/layout'
lookup exporting in js

Related

Defining MongoDB Image Array in Next JS

in the following code, how do I define itemData as post.images[i]?
import clientPromise from "../lib/mongodb";
import Box from '#mui/material/Box';
import Avatar from '#mui/material/Avatar';
import IconButton from '#mui/material/IconButton';
import ChatBubbleOutlineRoundedIcon from '#mui/icons-material/ChatBubbleOutlineRounded';
import FavoriteBorderRoundedIcon from '#mui/icons-material/FavoriteBorderRounded';
import ShareRoundedIcon from '#mui/icons-material/ShareRounded';
import Button from '#mui/material/Button';
import ImageList from '#mui/material/ImageList';
import ImageListItem from '#mui/material/ImageListItem';
export default function Posts({ posts }) {
return (
<div>
<ul>
<div style={{ width: '100%' }}>
<Box sx={{ display: 'flex', justifyContent: 'center'}}>
<div style={{ width: '75%' }}>
{posts.map((post) => (
<li style={{ border: '1px solid grey', borderRadius: '12px', margin: "10px", padding: "10px" }}>
<Box sx={{ display: 'flex', justifyContent: 'start', alignItems: 'center'}}>
<Avatar alt={post.userName} src={post.userAvatar}/>
<h4 style={{ paddingLeft:'20px', paddingRight: '20px' }}>{post.userName}</h4>
<p style={{ color: 'grey', fontSize: '12px' }}>{post.timestamp}</p>
</Box>
<Box>
<p style={{ display: 'block', width: '100%', margin: '0'}}>{post.text}</p>
</Box>
<Box sx={{ my: 1, display: 'flex', justifyContent: 'end', alignItems: 'center'}}>
<IconButton><ChatBubbleOutlineRoundedIcon/></IconButton>
<IconButton><FavoriteBorderRoundedIcon/></IconButton>
<IconButton><ShareRoundedIcon/></IconButton>
</Box>
<Box><Button href={post.link} variant="outlined">Link</Button></Box>
<Box>
<ImageList sx={{ width: 500, height: 450 }} cols={3} rowHeight={164}>
{itemData.map((item) => (
<ImageListItem key={item.img}>
<img
src={`${item.img}?w=164&h=164&fit=crop&auto=format`}
srcSet={`${item.img}?w=164&h=164&fit=crop&auto=format&dpr=2 2x`}
alt={item.title}
loading="lazy"
/>
</ImageListItem>
))}
</ImageList>
</Box>
</li>
))}
</div>
</Box>
</div>
</ul>
</div>
)
}
const itemData = [
{
img: 'https://images.unsplash.com/photo-1523217582562-09d0def993a6',
title: 'House',
},
{
img: 'https://images.unsplash.com/photo-1615874694520-474822394e73',
title: 'Living Room',
},
{
img: 'https://images.unsplash.com/photo-1616594039964-ae9021a400a0',
title: 'Bedroom',
},
{
img: 'https://images.unsplash.com/photo-1616486886892-ff366aa67ba4',
title: 'Dining Room',
},
{
img: 'https://images.unsplash.com/photo-1521783593447-5702b9bfd267',
title: 'Bathroom',
}
];
export async function getServerSideProps() {
try {
const client = await clientPromise;
const db = client.db("abode-app");
const posts = await db
.collection("posts")
.find({})
.sort({ metacritic: -1 })
.limit(20)
.toArray();
return {
props: { posts: JSON.parse(JSON.stringify(posts)) },
};
} catch (e) {
console.error(e);
}
}
I have tried loading the images one by one and they work, but prefer to loop over them.

How to dynamicly change elements at one page in React?

I am currently working on a react/typescript web shop and I have a problem. I have a JSON file that contains all product information and I have two components(pages) Home and Product.
On the Home page I imported a JSON file with products and with the help of the map method I created each product in the form of a link element, each link leads to a Product component that contains product details. I have 8 products, I could create eight different pages and each product has its page, but I would prefer to have one page for all products, with eight products, it is not terrible to have 8 different pages, but imagine there are 1000 products, is it possible to on click on different products on the home page, the content on the page with product details (Product component) changes dynamically.
These are my items.JSON:
[{
"id": 1,
"name": "Earphones",
"price": 49,
"imgUrl": "/images/earphones1.webp"},
{
"id": 2,
"name": "Earphones 2",
"price": 69,
"imgUrl": "/imgs/earphones2.webp"},
{
"id": 3,
"name": "Earphones 3",
"price": 59,
"imgUrl": "/imgs/earphones3.webp"},
{
"id": 4,
"name": "Earphones 4",
"price": 79,
"imgUrl": "/imgs/earphones4.webp"},
{
"id": 5,
"name": "Earphones 5",
"price": 79,
"imgUrl": "/imgs/earphones5.webp"},
{
"id": 6,
"name": "Speaker",
"price": 89,
"imgUrl": "/imgs/speaker.webp"},
{
"id": 7,
"name": "Watch",
"price": 199,
"imgUrl": "/imgs/watch.webp"},
{
"id": 8,
"name": "Watch2",
"price": 299,
"imgUrl": "/imgs/watch2.webp"}]
This is my Home.tsx:
import items from '../data/items.json'
import "../style/style.css"
import { Link } from 'react-router-dom';
export function Home(){
return (
<div>
<div
style={{
display: "flex",
flexWrap: "wrap",
justifyContent: "center",
gap: "20px",
}}
>
{items.map((item) => (
<Link
key={item.id}
style={{
textDecoration: "none",
color: "black",
}}
to={"/product"}
>
<div className="product-container">
<div
style={{
backgroundColor: "#e9ecef",
borderRadius: "20px",
padding: "10px",
}}
>
<img src={item.imgUrl} style={{}} width="250px" alt="" />
</div>
<div
style={{
display: "flex",
flexDirection: "column",
paddingInline: "20px",
fontFamily: "fantasy",
fontSize: "18px",
fontWeight: "lighter",
}}
>
<p style={{ color: "gray" }}>{item.name}</p>
<p
style={{
transform: "translateY(-30px)",
fontWeight: "bolder",
fontFamily: "cursive",
}}
>
${item.price}
</p>
</div>
</div>
</Link>
))}
</div>
</div>
);
}
And this is my Product.tsx:
import items from '../../data/items.json'
import '../../style/style.css'
import {
AiFillStar,
AiOutlineStar,
AiOutlineMinus,
AiOutlinePlus,
} from "react-icons/ai";
export function Product(){
return (
<div style={{ display: "grid", placeContent: "center" }}>
<div
style={{
display: "flex",
flexWrap: "wrap",
gap: "20px",
}}
>
<div
className="product-details-container"
style={{
display: "flex",
fontFamily: "monospace",
flexDirection: "column",
fontSize: "25px",
padding: "10px",
borderRadius: "10px",
}}
>
<img src={items[0].imgUrl} width="300px" alt="" />
</div>
<div style={{display: 'flex', flexDirection: 'column'}}>
<p
style={{
fontFamily: "monospace",
width: "300px",
textAlign: "left",
fontSize: "20px",
color: "#22223b",
}}
>
{items[0].name}
</p>
<div
style={{ color: "#ba181b", display: "flex", alignItems: "center" }}
>
<AiFillStar />
<AiFillStar />
<AiFillStar />
<AiFillStar />
<AiOutlineStar />
<p style={{ marginLeft: "5px", color: "#22223b" }}>(20)</p>
</div>
<p style={{fontFamily: 'monospace', fontSize: '20px'}}>${items[0].price}</p>
<div
style={{
fontFamily: "monospace",
color: "#22223b",
fontSize: "17px",
}}
>
<p>Details:</p>
<p>Cool headphones, amazing sound.</p>
</div>
<div
style={{
display: "flex",
alignItems: "center",
fontFamily: "monospace",
fontSize: "16px",
}}
>
<p style={{ marginRight: "20px" }}>Quantity:</p>
<button
style={{
background: "transparent",
border: "1px solid grey",
display: "grid",
placeContent: "center",
paddingInline: "20px",
height: "50px",
}}
>
<AiOutlineMinus />
</button>
<p
style={{
background: "transparent",
border: "1px solid grey",
display: "grid",
placeContent: "center",
paddingInline: "15px",
height: "48px",
}}
>
0
</p>
<button
style={{
background: "transparent",
border: "1px solid grey",
display: "grid",
placeContent: "center",
paddingInline: "20px",
height: "50px",
}}
>
<AiOutlinePlus />
</button>
</div>
<button
style={{
background: "transparent",
border: "1px solid darkred",
color: "darkred",
padding: '10px',
fontFamily: 'monospace',
fontSize: '17px',
width: '150px',
alignSelf: 'center'
}}
>
Add to Cart
</button>
</div>
</div>
</div>
);
}
In product component, all product details i got from the same JSON.
This is not a good approach to pass data from one route to other. See this link.
Anyway, I make a runnable code for you that will pass one Item object to Home page to Product page.
import { Link } from 'react-router-dom'
export interface Item {
id: number
name: string
price: number
imgUrl: string
}
const items: Item[] = [
{
id: 1,
name: 'Earphones',
price: 49,
imgUrl: '/images/earphones1.webp',
},
{
id: 2,
name: 'Earphones 2',
price: 69,
imgUrl: '/imgs/earphones2.webp',
},
{
id: 3,
name: 'Earphones 3',
price: 59,
imgUrl: '/imgs/earphones3.webp',
},
{
id: 4,
name: 'Earphones 4',
price: 79,
imgUrl: '/imgs/earphones4.webp',
},
{
id: 5,
name: 'Earphones 5',
price: 79,
imgUrl: '/imgs/earphones5.webp',
},
{
id: 6,
name: 'Speaker',
price: 89,
imgUrl: '/imgs/speaker.webp',
},
{
id: 7,
name: 'Watch',
price: 199,
imgUrl: '/imgs/watch.webp',
},
{
id: 8,
name: 'Watch2',
price: 299,
imgUrl: '/imgs/watch2.webp',
},
]
function Home() {
return (
<div
key={'App-1'}
style={{
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'center',
gap: '20px',
}}
>
{items.map((item, index) => (
<Link
key={`${index}-${item.id}`}
style={{
textDecoration: 'none',
color: 'black',
}}
to={{
pathname: `/product`,
search: JSON.stringify(item)
}}
>
// our code ....
</Link>
))}
</div>
)
}
export default App
And this is the modified Product.tsx page of yours.
import { useSearchParams } from "react-router-dom"
import { Item } from "./App";
export function Product(){
const [searchParam] = useSearchParams();
let item = {} as Item;
const data = Array.from(searchParam.keys());
if(data.length > 0) {
item= JSON.parse(data[0]);
}
return (<div>
{
item && item.id && <h1> {item.name}</h1>
// Your code
}
</div>)
}

How to remove the Scroll Bar in the body of the page in react js

I am stuck with a problem of unnecessary scroll in the page and i tried with various option like : Overflow:'hidden' but the problem is other JS component which are wrapped in the same class are looking good:
code with file name MapHome file:
import React from "react";
import {
makeStyles,
withStyles,
Typography,
Container,
Grid,
Box,
Button,
FormControl,
FormHelperText,
FormGroup,
} from "#material-ui/core";
import ellipse53 from '../Images/MapIt/MapHome/ellipse53.svg';
import rectangle13 from "../Images/MapIt/MapHome/rectangle13.svg";
import vector2 from "../Images/MapIt/MapHome/vector2.svg";
import mapIt from "../Images/MapIt/MapHome/mapIt.svg";
import frame214 from "../Images/MapIt/MapHome/frame214.svg";
import frame423 from "../Images/MapIt/MapHome/frame423.png";
import frame426 from "../Images/MapIt/MapHome/frame426.png";
import step1 from "../Images/MapIt/MapHome/step1.svg";
import step2 from "../Images/MapIt/MapHome/step2.svg";
import step3 from "../Images/MapIt/MapHome/step3.svg";
import finalStep from "../Images/MapIt/MapHome/finalStep.svg";
import Preview from "./Preview.js";
import PopupHome1 from './PopupHome1.js'
import PopupHome2 from "./PopupHome2";
//Checkbox library
import Checkbox from '#material-ui/core/Checkbox';
import CircleCheckedFilled from '#material-ui/icons/CheckCircle';
import CircleUnchecked from '#material-ui/icons/RadioButtonUnchecked';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import { Link } from "react-router-dom";
//form Library
const styles = makeStyles({
mapHome: {
minHeight: "1560px",
maxWidth: "1440PX",
overflow: "auto",
},
//*Main Grid
frame751: {
position: "static",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "1078px",
height: "1445px",
padding: "80px 181px 157px 181px",
},
//Background vector specification
rectangle13: {
position: "absolute",
left: "40px",
top: "-30px",
zIndex: 0,
},
vector2: {
position: "absolute",
left: "1070.84px",
top: "420.94px",
zIndex: 0,
},
ellipse53: {
position: "absolute",
left: "-100px",
top: "1273px",
zIndex: 0,
},
//1 Subgrid: Name:Map IT and
frame750: {
position: "relative",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "1078px",
height: "649px",
padding: "0px",
marginBottom: "64px",
},
mapIt: {
position: "static",
width: "293px",
height: "112px",
marginTop: "20px",
},
frame749: {
position: "relative",
display: "flex",
flexDirection: "row",
alignItems: "flex-start",
width: "1078px",
height: "509px",
padding: "0px",
top:'50px'
},
frame346: {
position: "static",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "301px",
height: "509px",
padding: "0px",
margin: "0px 142px 0px 0px",
},
frame518: {
position: "static",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "254.59px",
height: "241px",
padding: "0px",
margin: "24px 0px",
},
group36: {
position: "static",
width: "254.59px",
height: "185px",
margin: "0px 0px 8px 0px",
display: "flex",
flexDirection: "row",
alignItems: "flex-start",
},
frame426: {
position: "absolute",
margin: "58.14px 0px 56px 99.46px",
},
frame517: {
position: "static",
display: "flex",
flexDirection: "row",
alignItems: "flex-start",
justifyContent: "space-between",
width: "224px",
height: "48px",
padding: "0px",
},
frame215: {
position: "static",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "301px",
height: "196px",
padding: "0px",
},
frame216: {
position: "static",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "301px",
height: "88px",
padding: "0px",
margin:'0px 0px 24px 0px',
justifyContent:'space-between'
},
frame216info1:{
fontStyle:'normal',
fontWeight: 'bold',
fontSize: '16px',
lineHeight: '24px',
variant:'body',
fontFeatureSetting:'ss03 on',
},
frame217: {
position: "static",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "301px",
height: "84px",
padding: "0px",
justifyContent:'space-between'
},
frame217info2:{
fontStyle:'normal',
fontWeight: 'normal',
fontSize: '16px',
lineHeight: '24px',
variant:'body',
fontFeatureSetting:'ss03 on',
},
frame198: {
position: "static",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "635px",
height: "448px",
padding: "0px",
justifyContent:'space-between',
},
frame198Title:{
position: 'static',
width: '453px',
height: '48px',
fontStyle:'normal',
fontWeight: 'normal',
fontSize: '32px',
lineHeight: '48px',
variant:'h3',
fontFeatureSetting:'ss03 on',
color:'#24243F'
},
frame198info1:{
position: 'static',
width: '635px',
height: '64px',
fontStyle:'normal',
fontWeight: 'normal',
fontSize: '24px',
lineHeight: '32px',
variant:'subtitle',
fontFeatureSetting:'ss03 on',
color:'#2D86D9'
},
frame198info2:{
position: 'static',
width: '635px',
height: '160px',
fontStyle:'normal',
fontWeight: 'normal',
fontSize: '24px',
lineHeight: '32px',
variant:'subtitle',
fontFeatureSetting:'ss03 on',
color:'#24243F'
},
frame198info3:{
position: 'static',
width: '635px',
height: '128px',
fontStyle:'normal',
fontWeight: 'normal',
fontSize: '24px',
lineHeight: '32px',
variant:'subtitle',
fontFeatureSetting:'ss03 on',
color:'#24243F'
},
//2.SubGrid: Steps details and Checkbox
frame748: {
position: "relative",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "1077px",
height: "732px",
padding: "0px",
top:'64px'
},
frame538: {
position: "relative",
display: "flex",
flexDirection: "row",
alignItems: 'center' ,
width: "1077px",
height: "300px",
margin:'0px 0px 64px 0px',
left:'81px',
justifyContent:'space-between',
},
frame564:{
position: "relative",
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent:'space-between',
width: "915px",
height: "144px",
padding: "0px",
margin:'0px 0px 8px 0px',
left:'100px'
},
frame663:{
position: "static",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "170px",
height: "280px",
padding: "0px",
marginRight:'78.33px'
},
imageHover:{
"&:hover": {
transform:"rotate(-5deg)",
transition:'0.5s',
}
},
stepInfo:{
display:'flex',
alignItems:'center',
textAlign:'center',
justifyContent:'center',
color:'#000000',
fontStyle:'normal',
fontWeight: 'bold',
fontSize: '16px',
lineHeight: '24px',
variant:'body',
},
frame188:{
position: "relative",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "636px",
height: "400px",
padding: "0px",
marginLeft:'441px'
},
frame597:{
position: "relative",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
width: "636px",
height: "88px",
padding: "0px",
margin:'0px 0px 24px 0px'
},
frame597info1:{
position:'relative',
width:'452px',
fontStyle:'normal',
fontWeight: 'bold',
fontSize: '24px',
lineHeight: '32px',
variant:'h4',
color:'#24243F',
margin:'0px 0px 8px 0px'
},
frame597info2:{
position:'relative',
width:'636px',
fontStyle:'normal',
fontWeight: 'normal',
fontSize: '16px',
lineHeight: '24px',
variant:'body',
color:'#000000',
},
frame331:{
position: "relative",
display: "flex",
flexDirection: "column",
alignItems: "flex-start",
justifyContent:'space-between',
width: "636px",
height: "160px",
padding: "0px",
margin:'0px 0px 32px 0px'
},
frame213:{
position:'static',
display:'flex',
flexDirection:'column',
alignItems:'flex-start',
padding:'0px',
width:'579px',
height:'72px',
},
frame188button: {
borderRadius: "32px",
textTransform:"none",
width:"636px",
height:"64px",
fontWeight: '',
fontSize:"16px" ,
lineHeight: '24px',
variant:'body',
justifyContent:'center',
alignItems:'center',
padding:'10px 20px',
color:'white',
backgroundColor:'#24243F',
margin:'20px 0px 0px -10px',
},
});
// Checkbox Shape and color Customization //
const CustomColorCheckbox = withStyles({
root: {
color: "#BBBECC",
"&$checked": {
color: '#656C88'
},
margin: "16 px"
},
checked: {}
})((props) => <Checkbox color="default" {...props} />);
//schema definiion for Form using Yup
export default function MapHome() {
const classes = styles();
// State definition and handle change for checkbox
const [state, setState] = React.useState({
checked1: false,
checked2: false,
});
const handleChange = (event) => {
setState({
...state,
[event.target.name]: event.target.checked,
});
};
const { checked1, checked2} = state;
const error1 = [checked1].filter((v) => v).length !== 1;
const error2 = [checked2].filter((v) => v).length !== 1;
return (
<div style={{minHeight:'1600px'}} >
<Grid direction='column'>
<Grid item xs className={classes.rectangle13}>
<img src={rectangle13} alt="rectangle 13" />
</Grid>
<Grid item xs className={classes.vector2}>
<img src={vector2} alt="vector 2" />
</Grid>
<Grid item xs className={classes.ellipse53}>
<img src={ellipse53} alt="ellipse53" />
</Grid>
</Grid>
<Container className={classes.mapHome}>
<Grid direction="column" item xs className={classes.frame751}>
<Grid order="0" item xs className={classes.frame750}>
<Grid order="0" item xs className={classes.mapIt}>
<img src={mapIt} alt="MAP IT" />
</Grid>
<Grid
order="1"
item
xs
direction="row"
className={classes.frame749}
>
<Grid item xs direction="column" className={classes.frame346}>
<img src={frame214} alt="20 Minutes 3 Steps" />
<Box className={classes.frame518}>
<Box className={classes.group36}>
<img src={frame423} alt="20 Minutes 3 Steps" />
<img
src={frame426}
alt="20 Minutes 3 Steps"
className={classes.frame426}
/>
</Box>
<Box className={classes.frame517}>
<Preview />
</Box>
</Box>
<Box className={classes.frame215}>
<Box className={classes.frame216}>
<Typography className={classes.frame216info1}>What you will get</Typography>
<PopupHome1 />
<PopupHome2/>
</Box>
<Box className={classes.frame217}>
<Typography className={classes.frame216info1}>What you can use it for</Typography>
<Typography className={classes.frame217info2}>Funding applications</Typography>
<Typography className={classes.frame217info2}>Communication materials</Typography>
</Box>
</Box>
</Grid>
<Grid item xs direction="column" className={classes.frame198}>
<Typography className={classes.frame198Title}>What is this section about?</Typography>
<Typography className={classes.frame198info1}>
In this section you will map the story of your project in order to start measuring the impact of your work.
</Typography>
<Typography className={classes.frame198info2}>
Every project starts with hopes and expectations on how things will work out.
Once we start mapping our assumptions on how the project might progress,
we can begin to visualise our project’s journey, challenges it might face or
the knock on effects it might create.
</Typography>
<Typography className={classes.frame198info3}>
In three steps, you will go through questions modeled on the Theory of Change.
At the end of this section, you’ll get a project narrative written in your own words
and a visual version called ‘Story of Change’.
</Typography>
</Grid>
</Grid>
</Grid>
{/*Subgrid 2: Steps details and Checkbox*/}
<Grid order='1' direction='column' item xs className={classes.frame748} >
<Grid order='0' item xs className={classes.frame538}>
{/*step 1 Image with hover effect, css is defined in App.css file */}
<Box className={classes.frame663} component='div'>
<Box className="mapHomeImage">
<img src={step1} alt="step 1" className={classes.imageHover} />
<Box className="text" >Step 1 <br></br> About Your project</Box>
</Box>
<Box
className="hide"
mt={-1}
>
<ul>
<li className="li" ><Typography noWrap>Aim and Objective</Typography></li>
<li className="li" >Community</li>
<li className="li" >Result and Impact</li>
</ul>
</Box>
</Box>
{/*step 2 Image with hover effect, css is defined in App.css file */}
<Box className={classes.frame663} component='div'>
<Box className="mapHomeImage">
<img src={step2} alt="step 2" className={classes.imageHover} />
<Box className="text">Step 2 <br></br> Group Discussion</Box>
</Box>
<Box
className="hide"
mt={-1}
>
<Typography style={{textAlign:'center', marginTop:'16px'}} >Workshop guide for offline preparation</Typography>
</Box>
</Box>
{/*step 3 Image with hover effect, css is defined in App.css file */}
<Box className={classes.frame663} >
<Box className="mapHomeImage">
<img src={step3} alt="step 3" className={classes.imageHover}/>
<Box className="text" >Step 3 <br></br> Your story of change</Box>
</Box>
<Box
className="hide"
mt={-1}
>
<ul>
<li className="li" ><Typography noWrap>Background setting</Typography></li>
<li className="li" >Timelines</li>
<li className="li" >Enablers & barriers</li>
</ul>
</Box>
</Box>
{/* Final step Image with hover effect, css is defined in App.css file */}
<Box className={classes.frame663} component='div'>
<Box className="mapHomeImage">
<img src={finalStep} alt="final step" className={classes.imageHover} />
<Box className="text">Done!</Box>
</Box>
<Box
className="hide"
>
<Typography style={{textAlign:'center', marginTop:'16px'}} >A visual ‘story of change’ and a textual project narrative</Typography>
</Box>
</Box>
</Grid>
<Grid order='1' item xs className={classes.frame188}>
<Box className={classes.frame597}>
<Typography className={classes.frame597info1}>
Good to have before you start!
</Typography>
<Typography className={classes.frame597info2}>
In this section you’ll get an introduction to Theory of Change. It would be helpful if you had the following:
</Typography>
</Box>
<Box className={classes.frame331}>
<FormControl
required
error={error1}
component="fieldset"
variant="standard"
>
<FormGroup>
<FormControlLabel
style={{display:'table', marginBottom:'16px'}}
control={
<div style={{display:'table-cell'}}>
<CustomColorCheckbox
value={checked1}
onChange={handleChange}
name="checked1"
color="#24243F"
icon={<CircleUnchecked />}
checkedIcon={<CircleCheckedFilled />}
style={{transform: "scale(1.5)"}}
required
/>
</div>
}
label={
<Box ml={2} className={classes.frame213}>
<Typography
variant="body"
style={{color:"#24243F", fontSize:"16px",lineHeight:'24px', fontWeight:"bold"}}
>
A basic overview of your project
</Typography>
<FormHelperText variant='body' style={{fontSize:"16px",lineHeight:'24px',}}>
What is your project about? Who is it trying to help and why? Knowing just the basics about your project is good enough.
</FormHelperText>
</Box>
}
/>
</FormGroup>
</FormControl>
<FormControl
required
error={error2}
component="fieldset"
variant="standard"
>
<FormGroup>
<FormControlLabel
style={{display:'table', marginBottom:'32px'}}
control={
<div style={{display:'table-cell'}}>
<CustomColorCheckbox
value={checked2}
onChange={handleChange}
name="checked2"
color="#24243F"
icon={<CircleUnchecked />}
checkedIcon={<CircleCheckedFilled />}
style={{transform: "scale(1.5)"}}
required
/>
</div>
}
label={
<Box ml={2} className={classes.frame213}>
<Typography
variant="body"
style={{color:"#24243F", fontSize:"16px",lineHeight:'24px', fontWeight:"bold"}}
>
Time for offline activities
</Typography>
<FormHelperText variant='body' style={{ fontSize:"16px",lineHeight:'24px'}}>
You will need some time to have discussions with your target audience or project team members.
</FormHelperText>
</Box>
}
/>
</FormGroup>
</FormControl>
</Box>
<Button variant="contained" className={classes.frame188button} disabled={!(checked1 && checked2)} component={Link} to="/Main/MapItStep1">
Let's go!
</Button>
</Grid>
</Grid>
</Grid>
</Container>
</div>
);
}
I have wrapped this MapHome.js as Route in Main file Main.js:
import '../../App.css';
import MainHeader from '../Header/MainHeader.js'
import MainFooter from '../Footer/MainFooter.js'
import { BrowserRouter as Router,Route, Switch,useRouteMatch } from 'react-router-dom';
import MapHome from '../MapIt/MapHome.js';
import TrackHome from '../TrackIt/TrackHome.js';
import TellHome from '../TellIt/TellHome.js';
import Overview from './Overview.js';
import Contact from '../ContactUs/Contact.js'
import Terms from '../Privacy/Terms.js';
import Privacy from '../Privacy/Privacy.js';
import LandingHome from '../Landing/LandingHome.js';
import ScrollToTop from '../ScrollToTop';
import MapItStep1 from "../MapIt/MapStep1.js";
function Main() {
const { path } = useRouteMatch();
return (
<Router >
<ScrollToTop />
<Switch>
<div className='mainApp'>
<MainHeader/>
<div className="mainContent" >
<Route exact path={`${path}/`} component={Overview}/>
<Route exact path={`${path}/MapHome`} component={MapHome}/>
<Route exact path={`${path}/MapItStep1`} component={MapItStep1}/>
<Route exact path={`${path}/TrackHome`} component={TrackHome}/>
<Route exact path={`${path}/TellHome`} component={TellHome}/>
<Route exact path={`${path}/Contact`} component={Contact}/>
<Route exact path={`${path}/Terms`} component={Terms}/>
<Route exact path={`${path}/Privacy`} component={Privacy}/>
<Route exact path='/Landing' component={LandingHome}/>
</div>
<MainFooter/>
</div>
</Switch>
</Router>
);
};
export default Main;
Below is my App.css file:
.App {
display: flex;
flex-direction: column;
background: #fbf9f8;
position: relative;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
height: 100%;
width: 100%;
overflow-x: visible;
overflow-y: auto;
}
.mainApp {
display: flex;
flex-direction: column;
background: white;
position: relative;
box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
height: 100%;
width: 100%;
overflow-x: visible;
overflow-y: auto;
align-items: center;
},
.mainContent {
flex-grow: 1;
flex-shrink: 0;
flex-basis: auto;
position: relative;
align-items: flex-start;
min-height: 100%;
background: white;
overflow-x: visible;
overflow: auto;
max-width: 1440px;
width: 100%;
}
All the other Components which are wrapped in Main are looking good.
Can anyone help me on this.
Thanks in advance!!
I have found the problem as the problem was with 3 vectors defined which were overflowing out of the page. I have adjusted the margin of those vectors and problem is solved.

Creating dynamic html in React

Suppose I have a component that takes in MeetingData as an object and populates a <p> element with specific items from that object:
import React from 'react';
export default function MeetingsCard({ meetingData }) {
return (
<div className="col-xl-1-12" style={{ margin: "10px", background: "#1A4565", border: "double" }}>
<div className="card" style={{ border: "none", width: "100%" }}>
<div className="card-body" style={{ width: "100%", background: "lightBlue" }}>
<h3 className="card-title" style={{ marginLeft: "10px" }}>Meetings</h3>
<p style={{ marginLeft: "50px" }}>Meeting location: {meetingData.meeting_location}, Meeting Date: {meetingData.meeting_date}</p>
<hr style={{ color: "grey" }} />
</div>
</div>
</div>
)
}
In this case, it expects there 2 be only a single item for meetingData.meeting_date and a single item for meetingData.meeting_location. But suppose the returned object has more than one and I need to populate multiple <p> elements? How would I do that if the meeting object/array looks like this:
meetingData = [
{
"date_time": "2021-07-07",
"meeting_location": "test-location1",
"name": "John Doe"
},
{
"date_time": "2021-07-08",
"meeting_location": "test-location2",
"name": "John Doe"
}
]
Just loop your data and add each entry as their own. Also good idea to create own component for the meeting entries so that it's easier to customize it if necessary.
MeetingEntry:
import React from 'react';
export default function MeetingEntry({ meetingData }) {
return (
<p style={{ marginLeft: "50px" }}>Meeting location: {meetingData.meeting_location}, Meeting Date: {meetingData.meeting_date}</p>
)
}
MeetingsCard:
import React from 'react';
import MeetingEntry from './MeetingEntry';
export default function MeetingsCard({ data }) {
return (
<div className="col-xl-1-12" style={{ margin: "10px", background: "#1A4565", border: "double" }}>
<div className="card" style={{ border: "none", width: "100%" }}>
<div className="card-body" style={{ width: "100%", background: "lightBlue" }}>
<h3 className="card-title" style={{ marginLeft: "10px" }}>Meetings</h3>
{data.map((el, idx) => (
<MeetingEntry notification={el} key={idx} />
))}
<hr style={{ color: "grey" }} />
</div>
</div>
</div>
)
}
You can just loop through the array and display data something like below
export default function MeetingsCard({ meetingData }) {
return (
<div className="col-xl-1-12" style={{ margin: "10px", background: "#1A4565", border: "double" }}>
<div className="card" style={{ border: "none", width: "100%" }}>
<div className="card-body" style={{ width: "100%", background: "lightBlue" }}>
<h3 className="card-title" style={{ marginLeft: "10px" }}>Meetings</h3>
{meetingData.map(meeting => (
<p style={{ marginLeft: "50px" }}>Meeting location: {meeting.meeting_location}, Meeting Date: {meeting.date_time}</p>))
<hr style={{ color: "grey" }} />
</div>
</div>
</div>
)
}

Creating Tweet Display Box in ReactJS

I am using the following code to generate a Tweet input box which takes in text/video/image/emoji. And they can be in different combinations.
I am not sure how to generate a tweet display box which shows the final display containing text/image/emoji ? I understand I might need to put the different inputs in an array or some sort but what after that. My current code for display side is performing nothing and I am not sure where to go from here.
I am looking for display box to be of following form after a Submit Button:
Code components/EmojiPicker.js has:
import React, {useState} from 'react'
import ReactDOM from "react-dom";
import { Picker } from "emoji-mart";
import Button from "#material-ui/core/Button";
const EmojiPicker = ({ onSelect }) => {
const [show, setShow] = useState(false);
return (
<>
<Button
onClick={() => setShow(oldState => !oldState)}
style={{ width: "30px", height: "30px", borderRadius: "4px", border: "3px solid", display: "flex", alignItems: "center", justifyContent: "center",
background: "transparent"}}>
ej
</Button>
{ReactDOM.createPortal(
show && <Picker onSelect={onSelect} />,
document.body
)}
</>
);
};
export default EmojiPicker
Code components/FileInput.js has:
import React, {useRef} from 'react'
const FileInput = ({ onChange, children }) => {
const fileRef = useRef();
const onPickFile = event => {
onChange([...event.target.files]);
};
return (
<div
style={{
width: "35px",
height: "35px",
borderRadius: "3px"
}}
onClick={() => fileRef.current.click()}
>
{children}
<input
multiple
ref={fileRef}
onChange={onPickFile}
type="file"
style={{ visibility: "hidden" }}
/>
</div>
);
};
export default FileInput
Code components/tweetboxImgInp.js as:
import React, {useState, useEffect} from 'react'
const ImgIcon = () => (
<svg focusable="false" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path d="M0 0h24v24H0z" fill="none" />
<path d="M14 13l4 5H6l4-4 1.79 1.78L14 13zm-6.01-2.99A2 2 0 0 0 8 6a2 2 0 0 0-.01 4.01zM22 5v14a3 3 0 0 1-3 2.99H5c-1.64 0-3-1.36-3-3V5c0-1.64 1.36-3 3-3h14c1.65 0 3 1.36 3 3zm-2.01 0a1 1 0 0 0-1-1H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h7v-.01h7a1 1 0 0 0 1-1V5z" />
</svg>
);
export const Img = ({ file, onRemove, index }) => {
const [fileUrl, setFileUrl] = useState(null);
useEffect(() => {
if (file) {
setFileUrl(URL.createObjectURL(file));
}
}, [file]);
return fileUrl ? (
<div style={{ position: "relative", maxWidth: "230px", maxHeight: "95px" }}>
<img
style={{
display: "block",
maxWidth: "230px",
maxHeight: "95px",
width: "auto",
height: "auto"
}}
alt="pic"
src={fileUrl}
/>
<div
onClick={() => onRemove(index)}
style={{
position: "absolute",
right: 0,
top: 0,
width: "20px",
height: "20px",
borderRadius: "50%",
background: "black",
color: "white",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
x
</div>
</div>
) : null;
};
export default ImgIcon
And App.js has:
import React, { useRef, useState } from "react";
import ImgIcon, {Img} from './components/tweetboxImgInp'
import EmojiPicker from './components/EmojiPicker'
import FileInput from './components/FileInput'
import "emoji-mart/css/emoji-mart.css";
import "./styles.css";
function App() {
const [text, setText] = useState("");
const [pics, setPics] = useState([]);
const textAreaRef = useRef();
const insertAtPos = value => {
const { current: taRef } = textAreaRef;
let startPos = taRef.selectionStart;
let endPos = taRef.selectionEnd;
taRef.value =
taRef.value.substring(0, startPos) +
value.native +
taRef.value.substring(endPos, taRef.value.length);
};
return (
<div style={{display: "flex", flexDirection: "column", border: "3px solid", borderRadius: "5px", width: "600px", minHeight: "200px", padding: "20px"}} >
<div style={{ display: "flex", flexDirection: "column", flex: 1, border: "1px solid", borderRadius: "5px", margin: "0px"}}>
<textarea
ref={textAreaRef}
value={text}
style={{ flex: 1, border: "none", minHeight: "150px" }}
onChange={e => setText(e.target.value)}
/>
<div style={{ display: "flex", flexDirection: "row", flexWrap: "wrap", background: "fbfbfb"}} >
{pics.map((picFile, index) => (
<Img key={index} index={index} file={picFile} onRemove={rmIndx =>
setPics(pics.filter((pic, index) => index !== rmIndx))}/>))}
</div>
</div>
<div style={{ display: "flex", flexDirection: "row", alignItems: "center", marginTop: "20px" }}>
<div style={{ marginRight: "20px" }}>
<FileInput onChange={pics => setPics(pics)}>
{/* <ImgIcon /> */}
Tes
</FileInput>
</div>
<EmojiPicker onSelect={insertAtPos} />
</div>
</div>
);
}
export default App
Edit: I am good with the display box accepting only 1 media file, text and few emoji. It will surprise me if I am the only one in 2019 looking to do it for fun.
Working Example
Click the codesandbox button to view the demo
The tweet display component is pretty straightforward. Its a flexbox column with two parts. First part of the column contains the tweet. The second part of the column contains the list of images/media elements. Emoji is part of the text component.
Tweet Display Component
const Tweet = ({ tweet: { text, images } }) => (
<div
style={{
margin: "20px",
border: "1px solid grey",
width: "600px",
padding: "20px",
borderRadius: "3px"
}}
>
<div>{text}</div>
{images.length > 0 && (
<div
style={{
display: "flex",
flexDirection: "row",
flexWrap: "wrap",
background: "fbfbfb",
padding: "30px 0"
}}
>
{images.map((img, i) => (
<Img key={i} file={img} index={i} isSingle={images.length === 1} />
))}
</div>
)}
</div>
);
For more info checkout this css-tricks article to get more info on css flex layout

Resources