React DnD, could not find "store" in the context of Connect(Droppable) - javascript

Hello I am trying to make a drag and drop in my application but I have got a huge error. I have no idea if property is missing because in IDE it is an error free code.
Uncaught Error: Could not find "store" in the context of "Connect(Droppable)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(Droppable) in connect options.
Down here are my components
3 Columns ( I want drag and drop across one column each, not between them)
const DetailColumns: React.FC<funcProps> = (props) => {
const onDragEnd = () => {};
return (
<Box
h="80vh"
borderWidth="0.5rem"
borderColor="orange.300"
borderRadius="1rem"
w="80%"
marginTop="2rem"
>
<Grid w="100%" h="100%" templateColumns="60% 20% 20%">
<Box border="0.5rem" borderColor="orange.300">
<RecipeDescriptionBox recipe={props.recipe} />
</Box>
<Box borderLeftWidth="0.5rem" borderColor="orange.300">
<RecipeStepsBox recipe={props.recipe} />
</Box>
<DragDropContext onDragEnd={onDragEnd}>
<Box borderLeftWidth="0.5rem" borderColor="orange.300">
<RecipeIngredientsBox recipe={props.recipe} />
</Box>
</DragDropContext>
</Grid>
</Box>
);
};
List of Items
<Box>
<ColumnHeader title="Steps" />
<Droppable droppableId="unique">
{(provided) => (
<Box {...provided.droppableProps} innerRef={provided.innerRef}>
{steps.map((step, index) => (
<DetailListItem
key={step}
itemName={step}
indexOfItem={index}
id={Math.random().toString()}
/>
))}
{provided.placeholder}
</Box>
)}
</Droppable>
</Box>
Item element
<Draggable draggableId={props.id} index={props.indexOfItem}>
{(provided) => (
<Box
{...provided.draggableProps}
{...provided.dragHandleProps}
innerRef={provided.innerRef}
>
<Flex margin="1rem">
<Box
bgGradient="linear(to-r, orange.200, orange.400)"
height="6vh"
width="6vh"
boxShadow="md"
rounded="md"
>
<Grid w="100%" h="100%" placeItems="center">
<Text color="white" fontWeight="700" fontSize="140%">
{props.amount && props.amount + props.unit}
{!props.amount && props.indexOfItem}
</Text>
</Grid>
</Box>
<Grid placeItems="center">
<Text marginLeft="1rem" fontWeight="500" fontSize="1.8rem">
{props.itemName}
</Text>
</Grid>
</Flex>
</Box>
)}
</Draggable>
If you want I can put this code to some sandbox to make it easier to debug.

Related

Not able to see the updated values in react after creating a group

I am trying to perform a simple exercise, wherein I am showing the data from the local JSON file saved in my folder, and then reading it to show the data with useState, such that when a user clicks in he can edit the author and location filed and save it.
The issue I get is when I save the data in my group or location it does not populate the new value, however, it just removes the new value, but when I filter and select all values from the dropdown I can see the values in there.
Can anyone please let me know what is the missing part here? I want to achieve the task that when a user updates the value on the author group or location group they should be there with the new group value.
Please the link to the code below and a working demo on codeSandbox
watch the full code and demo here
The source code for the author group component I tried so far;
import { useEffect, useState } from "react";
import {
Container,
Accordion,
AccordionSummary,
AccordionDetails,
Typography,
Button
} from "#mui/material";
import ExpandMoreIcon from "#mui/icons-material/ExpandMore";
import EditIcon from "#mui/icons-material/Edit";
const Authorsgroup = ({
posts,
groupDropdownValue,
setShowForm,
setPostId,
showForm
}) => {
const authorGroup = posts.reduce((group, authorgroup) => {
(group[authorgroup.author.replace(/ +/g, "")] =
group[authorgroup.author.replace(/ +/g, "")] || []).push(authorgroup);
return group;
}, {});
const [authorGroupValues, setAuthorGroupValues] = useState(authorGroup);
useEffect(() => {
setAuthorGroupValues(authorGroup);
console.log(authorGroupValues);
}, [groupDropdownValue, showForm]);
return (
<>
{/* all gorupby authors */}
<Container>
{/* show group of Tapesh */}
<Container style={{ marginTop: "3rem" }}>
{authorGroupValues?.Tapesh.map((post, index) => (
<Accordion key={index}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography variant="h6" style={{ color: "#EB1283" }}>
{post.id} {post.author} {post.location}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography variant="h4">{post.location}</Typography>
<Typography>{post.text}</Typography>
<Button
variant="outlined"
onClick={() => {
setShowForm(!showForm);
setPostId(post.id);
}}
startIcon={<EditIcon />}
>
Edit
</Button>
</AccordionDetails>
</Accordion>
))}
</Container>
{/* show group of HappyManager */}
<Container style={{ marginTop: "3rem" }}>
{authorGroupValues?.HappyManager.map((post, index) => (
<Accordion key={index}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography variant="h6" style={{ color: "orange" }}>
{post.id} {post.author} {post.location}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography variant="h4">{post.location}</Typography>
<Typography>{post.text}</Typography>
<Button
variant="outlined"
onClick={() => {
setShowForm(!showForm);
setPostId(post.id);
}}
startIcon={<EditIcon />}
>
Edit
</Button>
</AccordionDetails>
</Accordion>
))}
</Container>
{/* show group of HappyDeveloper */}
<Container style={{ marginTop: "3rem" }}>
{authorGroupValues?.HappyDeveloper.map((post, index) => (
<Accordion key={index}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography variant="h6" style={{ color: "green" }}>
{post.id} {post.author} {post.location}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography variant="h4">{post.location}</Typography>
<Typography>{post.text}</Typography>
<Button
variant="outlined"
onClick={() => {
setShowForm(!showForm);
setPostId(post.id);
}}
startIcon={<EditIcon />}
>
Edit
</Button>
</AccordionDetails>
</Accordion>
))}
</Container>
{/* show group of HappyUser */}
<Container style={{ marginTop: "3rem" }}>
{authorGroupValues?.HappyUser.map((post, index) => (
<Accordion key={index}>
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls="panel1a-content"
id="panel1a-header"
>
<Typography variant="h6" style={{ color: "red" }}>
{post.id} {post.author} {post.location}
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography variant="h4">{post.location}</Typography>
<Typography>{post.text}</Typography>
<Button
variant="outlined"
onClick={() => {
setShowForm(!showForm);
setPostId(post.id);
}}
startIcon={<EditIcon />}
>
Edit
</Button>
</AccordionDetails>
</Accordion>
))}
</Container>
</Container>
</>
);
};
export default Authorsgroup;
Thanks any suggestions or help are really appreciated.

Warning: Failed prop type: The prop `justify` of `ForwardRef(Grid)` is deprecated. Use `justifyContent` instead, the prop was renamed

Can someone help me in solving this error.
I am unable to rectify this error.
this is what i got in the browser's console
const Cart = ({ cart }) => {
const classes = useStyles();
const EmptyCart = () => (
<Typography variant="subtitle1">
You have no items in your cart, start adding some!!!
</Typography>
);
const FilledCart = () => (
<>
<Grid container spacing={3}>
{cart.line_items.map((item) => (
<Grid item xs={12} sm={4} key={item.id}>
<CartItem item={ item }/>
</Grid>
))}
</Grid>
<div className={classes.cardDetails}>
<Typography variant='h4'>
Subtotal: {cart.subtotal.formatted_with_symbol}
</Typography>
<Button className={classes.emptyButton} size="large" type="button" variant="contained" color="secondary">Empty cart</Button>
<Button className={classes.checkoutButton} size="large" type="button" variant="contained" color="primary">Checkout</Button>
</div>
</>
)
if (!cart.line_items)
return '.......loading';
return (<Container>
<div className={classes.toolbar} />
<Typography className={classes.title} variant='h3' gutterBottom>
Your Shopping Cart
</Typography>
{!cart.line_items.length ? <EmptyCart /> : <FilledCart />}
</Container>);
};
export default Cart;
Note that The prop justify is deprecated, use justifyContent instead.
So, replace justify by justifyContent.
Before :
<Grid container **justify="space-between"** alignItems="center" spacing={4}>
After:
<Grid container **justifyContent="space-between"** alignItems="center" spacing={4}>
I was checked official document but no luck, after that I did custom styling in following way and it work fine for me.
Error:
<Grid
container
direction="row"
justifyContent="center"
alignItems="center"
>
Solution:
<Grid
container
direction="row"
style={{justifyContent:"center"}}
alignItems="center"
>

Handling onClick for a particular element in react

I am trying to make a card grid where the user can expand the card to view its details. The issue I am facing with the react hooks is that the function is getting called for all cards instead of the particular card I am clicking the button. As a result, all the cards are getting expanded.
Here's my code for reference.
Any help is highly appreciated. Thank you!
function Album(props) {
return (
<div>
<Card className={classes.card}>
<Card.Text >
<p className={classes.heading}>
{props.blogTitle}
</p>
</Card.Text>
<Card.Body>
<Card.Img
src={props.imgsrc}
alt="Card image"
className={classes.cardMedia}
/>
{props.cardOpen &&
<AnimatePresence>
<motion.div
initial={{opacity:0}}
animate={{opacity:1, transition:0.3}}
>
<p className={classes.desc} gutterbottom>
{props.blogDescription}
</p>
<div href={props.blogLink}
style={{color:"gray", fontSize:17, fontFamily:"calibri", fontSmooth: "auto", cursor:"pointer", display:"flex", justifyContent:"center"}}>
<LocalLibraryIcon style={{marginRight:7}}/>Read blog
</div>
</motion.div>
</AnimatePresence>
}
{(props.cardOpen) ?
<div onClick={props.isOpen} style={{float:"right", cursor:"pointer"}}>
<ExpandLessIcon style={{fontSize:40, marginTop:10, color:" #909090"}}/>
</div> : (
<div onClick={props.isOpen} style={{float:"right", cursor:"pointer"}}>
<ExpandMoreIcon style={{fontSize:40, marginTop:10, color:" #909090"}}/>
</div>
)}
</Card.Body>
</Card>
</div>
);
}
export default function ProjectItems() {
const [cardOpen, setCardOpen]= useState(false);
return (
<React.Fragment>
<CssBaseline />
<main>
<div className={classes.heroContent}>
<Container maxWidth="md">
<Typography
variant="h2"
align="center"
color="textPrimary"
className={classes.root}
gutterBottom
>
Blogs
</Typography>
</Container>
</div>
<Container maxWidth="md">
<Grid container spacing={4}>
{blogData.map(post => (
<Grid item xs={12} sm={6} md={4} key={post.id}>
<div>
<Album
blogId={post.id}
blogTitle={post.title}
blogDescription={post.summary}
imgsrc={post.image_link}
blogLink={post.article_link}
isOpen={()=>{
setCardOpen(!cardOpen);
}}
cardOpen={cardOpen}
/>
</div>
</Grid>
))}
</Grid>
</Container>
</main>
</React.Fragment>
);
}

How to fix button to be interacted with, in carousel?

When I try to import a layer/button onto one of these cards it does not allow it to be clicked or interacted with. I believe the problem is with the carousel. What is a way I can fix this? The "CenterLayer" is supposed to act as a button and is the one I am having problems with. When I put this code the layer appears on the card as a footer but it's not allowed to be clicked. Is there anyone that can help me with this, please?
import React from "react";
import {
Card,
CardHeader,
CardBody,
CardFooter,
Box,
Image,
Heading,
Carousel,
Grommet,
Calendar,
Text,
} from "grommet";
import {CenterLayer} from "./EventsButton";
import { MainFooter } from "../Footer/Footer";
const Card0 = () => (
<Card pad="large" background="dark-1" gap="medium">
<CardHeader>
<Box height="small" width="small">
<Image src="./images/Photo.jpg" />
</Box>
</CardHeader>
<CardBody>The Stranahan High School Graduation</CardBody>
<Box direction="row" round gap="xlarge">
<CardFooter>
3/25/2021
</CardFooter>
<CardFooter>
<CenterLayer />
</CardFooter>
</Box>
</Card>
);
const Card1 = () => (
<Card pad="large" background="dark-1" gap="medium">
<CardHeader>
<Box height="small" width="small">
<Image src="./images/Photo.jpg" />
</Box>
</CardHeader>
<CardBody>Card1 The Stranahan High School Graduation</CardBody>
<CardFooter>Footer</CardFooter>
</Card>
);
const Card2 = () => (
<Card pad="large" background="dark-1" gap="medium">
<CardHeader>
<Box height="small" width="small">
<Image src="./images/Photo.jpg" />{" "}
</Box>
</CardHeader>
<CardBody>Card2 The Stranahan High School Graduation</CardBody>
<CardFooter>Footer</CardFooter>
</Card>
);
const Events = () => (
<Grommet>
<Heading textAlign="center" size="large" alignSelf="center" level="2" margin={{ left: "xlarge",
top: "large",}}>Upcoming Events</Heading>
<Carousel>
<Box direction="row" pad="large" round gap="small">
<Card0 />
<Card1 />
<Card2 />
</Box>
<Box direction="row" pad="large" round gap="small">
<Card1 />
<Card0 />
<Card2 />
</Box>
<Box direction="row" pad="large" round gap="small">
<Card2 />
<Card1 />
<Card0 />
</Box>
<Box direction="row" pad="large" round gap="small">
<Card1 />
<Card0 />
<Card2 />
</Box>
</Carousel>
<Heading textAlign="center" size="large" alignSelf="center" level="2" margin={{ left: "xlarge",
top: "large",}}>Past Events</Heading>
<Carousel>
<Box direction="row" pad="large" round gap="small">
<Card0 />
<Card1 />
<Card2 />
</Box>
<Box direction="row" pad="large" round gap="small">
<Card1 />
<Card0 />
<Card2 />
</Box>
<Box direction="row" pad="large" round gap="small">
<Card2 />
<Card1 />
<Card0 />
</Box>
<Box direction="row" pad="large" round gap="small">
<Card1 />
<Card0 />
<Card2 />
</Box>
</Carousel>
<Box direction="row" pad="xlarge" round gap="xlarge">
<Box height="medium" width="medium" margin={{left: "xlarge"}}>
<Calendar fill daysOfWeek />
</Box>
<Box margin={{left: "xlarge", top:"large"}}>
<Card background={'orange'} >
<CardBody height="medium" width="medium" margin={{right: "medium", bottom: "medium", left: "medium", top: "medium"}}>
<Text>At SEEF we take every opportunity to help the Stranahan community. We hope that our impact will lead others to do the same.</Text>
</CardBody>
</Card>
</Box>
</Box>
< MainFooter />
</Grommet>
);
export default Events
import React from 'react';
import { Add } from 'grommet-icons';
import { Box, Button, Grommet, Heading, Layer, Select, Text } from 'grommet';
import { grommet } from 'grommet/themes';
export const CenterLayer = () => {
const [open, setOpen] = React.useState();
const onOpen = () => setOpen(true);
const onClose = () => setOpen(undefined);
return (
<Grommet theme={grommet} >
<Box fill align="center" justify="center">
<Button
icon={<Add />}
label={
<Text>
<strong>More Information</strong>
</Text>
}
onClick={onOpen}
plain
/>
</Box>
{open && (
<Layer position="center" onClickOutside={onClose} onEsc={onClose}>
<Box pad="medium" gap="small" width="medium">
<Heading level={3} margin="none">
The Stranahan High School Graduation
</Heading>
<Text>This event will be taken place at City Hall in Fort Lauderdale</Text>
<Text>This event will be taken place on 3/25/2021 at 3:00PM</Text>
<Box
as="footer"
gap="small"
direction="row"
align="center"
justify="end"
pad={{ top: 'medium', bottom: 'small' }}
>
<Button
label={
<Text color="white">
<strong>Close</strong>
</Text>
}
onClick={onClose}
primary
color="status-critical"
/>
</Box>
</Box>
</Layer>
)}
</Grommet>
);
};
CenterLayer.storyName = 'Center';
CenterLayer.parameters = {
chromatic: { disable: true },
};
export default {
title: 'EventsButton',
};
Carousel is an interactive element, i.e. it has its own focus and navigation behavior, and for UX & accessibility reasons you shouldn't place nested interactive elements inside of each other, hence I'd try to avoid a button inside of a card, inside of a Carousel.
That being said, the button you've placed in the card is placed 'behind' the Carousel, so moving up its z-index would solve the problem.
Add this style to a Card and it should do trick
<Card style={{ zIndex: "100" }} ... >
I chose 100 as a random number, feel free to make it smaller according to your app behavior.

Setting onClick to false

I currently have a table using a slider to provide additional details for a table. When the slider component opens I have an X to close to the slider. I am attempting to have that X close the slider and have the table in its original form appear.
Here is a code sandbox:
code sandbox
Slider component :
function ExpandToggle(isOpenProps) {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => {
setIsOpen(!isOpen);
};
return (
<>
<Button>
<ArrowForwardIosIcon size="small" onClick={toggle} />{" "}
</Button>
<SliderInfo open={isOpen} />
</>
);
}
SliderInfo component with onClick={open=false}
export default function SliderInfo({ open }) {
const classes = useStyles();
return (
<Slide direction="left" in={open} mountOnEnter unmountOnExit>
<div className={classes.root}>
<Grid container>
<Grid item>
<Typography variant="h6">Vanila Ice Cream</Typography>
</Grid>
<Grid item>
<Typography variant="h6">Chocolate Ice Cream</Typography>
</Grid>
<Grid item>
<Typography variant="h6">Strawberry Ice Cream</Typography>
</Grid>
<Grid item>
<Typography variant="h6">Sherbert </Typography>
</Grid>
<Grid item>
<Typography variant="h6">None</Typography>
</Grid>
<Grid item>
<Button>
<CloseIcon onClick={open=false} />
</Button>
</Grid>
</Grid>
</div>
</Slide>
On CloseIcon I have an onClick that i'm trying to set open which is passed from Slider to false so it can close the slider component. At the moment upon clicking on the CloseIcon it is not do anything.
Don't modify props directly.
Pass in the toggle function just like you passed in the open variable, and call it instead.
<SliderInfo open={isOpen} toggleOpen={toggle} />
// In Sliderinfo
export default function SliderInfo({ open, toggleOpen }) {
...
<CloseIcon onClick={toggleOpen} />
If your toggle doesn't serve the same purpose, create a new function that only sets isOpen to false and use it instead.
Also remember that onClick expects a function. So the open=false is actually getting executed during render, not after a click. Correct inline format would be onClick={(e) => {//do stuff}}.
You can pass a callback function to the Slider that can call your setIsOpen state modifier, and then pass it to onClick:
function ExpandToggle(isOpenProps) {
const [isOpen, setIsOpen] = useState(false);
const toggle = () => {
setIsOpen(!isOpen);
};
return (
<>
<Button>
<ArrowForwardIosIcon size="small" onClick={toggle} />{" "}
</Button>
<SliderInfo open={isOpen} onRequestClose={() => { setIsOpen(false) }} />
</>
);
}
export default function SliderInfo({ open, onRequestClose }) {
const classes = useStyles();
return (
<Slide direction="left" in={open} mountOnEnter unmountOnExit>
<div className={classes.root}>
<Grid container>
<Grid item>
<Typography variant="h6">Vanila Ice Cream</Typography>
</Grid>
<Grid item>
<Typography variant="h6">Chocolate Ice Cream</Typography>
</Grid>
<Grid item>
<Typography variant="h6">Strawberry Ice Cream</Typography>
</Grid>
<Grid item>
<Typography variant="h6">Sherbert </Typography>
</Grid>
<Grid item>
<Typography variant="h6">None</Typography>
</Grid>
<Grid item>
<Button>
<CloseIcon onClick={onRequestClose} />
</Button>
</Grid>
</Grid>
</div>
</Slide>

Categories