javascriptreactjssemantic-uisimplemodal

React.js Popup modal for shopping cart


I am currently working on a shopping cart and I am trying to figure out how to have the modal appear once I click on the shopping cart icon. I have looked at the documentation for the semantic-ui for modals but it is vague as to how to get the modal to appear when clicking on something. I am using the semantic-ui class="ui modal" for the modal.

I was thinking of putting an onClick on the icon but was still confused as to how to go from there. Currently, I have the icon in another component and the shopping cart in another separate component. I want the items to appear inside of the pop-up modal which should be the shopping cart.

import React from 'react'
import { Icon } from 'semantic-ui-react';

const ShoppingCartIcon = () => {



   return(

     <Icon.Group size='big' className="shopping_cart_icon">
       <Icon link name='shopping cart'/>
       <Icon corner='top right'/>
   </Icon.Group>
)


}
export default ShoppingCartIcon;


  import React from 'react'
  import Shirt from './Shirt';

   class ShoppingCart extends React.Component {

    render() {

   const listShirts = this.props.shirts.map(shirt => {
     return <Shirt key={shirt.id} {...shirt}/>
   })

   return(
     <div className="ui modal">
       <div className="content">
         {listShirts}
      </div>
     </div>
    )
   }

 }
 export default ShoppingCart;

Currently, I do not have the functionality for adding items to the cart working yet. I just want to focus on getting the modal to show up once I click on the shopping cart icon


Solution

  • as far as I see, you are not using neither redux nor context api. you are passing props with props drilling.

    so this is how you should organize your code step by step.

    we render cartIcon component in the header.js. here is a classic header

    Header.js

    import CartDropdown from "../cart-dropdown/cart-dropdown.component";
    
    class Header extends React.Component {
      constructor(props) {
        super(props);
        state = { hidden: true,       cartItems:[]};
      }
      toggleHidden() {
        this.setState(() => ({ hidden: !this.state.hidden }));
      }
      render() {
        return (
          <div className="header">
            <Link className="logo-container" to="/">
              <Logo className="logo" />
            </Link>
            <div className="options">
              <Link className="option" to="/shop">
                SHOP
              </Link>
              <Link to="/contact" className="option">
                CONTACT
              </Link>
              {/* <Link></Link> */}
    
              <CartIcon />
            </div>
            {hidden ? null : (
              <CartDropdown
                toggle={this.toggleHidden}
                cartItems={this.state.cartItems}
              ></CartDropdown>
            )}
          </div>
        );
      }
    }
    

    you said you have not set the addItem functionality yet. as you add items to the cartItems array you will display them in the cart.

    now we need to set up the cartDropdown component.

    const CartDropdown = ({ cartItems, toggleHidden }) => (
      <div className="cart-dropdown">
        <div className="cart-items">
          {cartItems.length ? (
            cartItems.map(item => <CartItem key={item.id} item={item} />)
          ) : (
            <span className="empty-message"> Your cart is empty </span>
          )}
        </div>
        <CustomButton
          onClick={() => {
    
            toggleHidden();
          }}
        >
          GO TO CHECKOUT
        </CustomButton>
      </div>
    );
    

    here we need to add css for cartDropdown. I do not how you are dealing with your css. prop-types or scss but here is the css code so you can apply to your project.

    css for cartDropdown component

    .cart-dropdown {
      position: absolute;
      width: 240px;
      height: 340px;
      display: flex;
      flex-direction: column;
      padding: 20px;
      border: 1px solid black;
      background-color: white;
      top: 80px;
      right: 0;
      z-index: 5;
      .cart-items {
        height: 240px;
        display: flex;
        flex-direction: column;
        overflow: scroll;
      }
      .empty-message {
        font-size: 18px;
        margin: 50px auto;
      }
      button {
        margin-top: auto;
      }
    }