project/final project 술고래

2023.08.20 모달창 바깥을 눌러도 닫히도록 설정등 기능 수정 및 추가

campanula 2023. 8. 20. 08:54
import React, { useState, useRef, useEffect } from 'react';
import './Modal.css';

const Modal = () => {
  const dialogRef = useRef();
  const [isOpen, setOpen] = useState(false);

  const handleOpenModal = () => {
    dialogRef.current.showModal();
    setOpen(true);
  };

  const handleCloseModal = () => {
    dialogRef.current.close();
    setOpen(false);
  };

  const handleOverlayClick = (event) => {
    if (event.target === dialogRef.current) {
      handleCloseModal();
    }
  };

  useEffect(() => {
    window.addEventListener('click', handleOverlayClick);
    return () => {
      window.removeEventListener('click', handleOverlayClick);
    };
  }, [isOpen]);

  return (
    <div>
      <button onClick={handleOpenModal}>Open Modal</button>
      <dialog ref={dialogRef} open={isOpen}>
        <button className="close-button" onClick={handleCloseModal}>
          X
        </button>
        <h2>Modal Content</h2>
        <p>This is a modal example using the dialog element tag.</p>
        <button className="next-button" onClick={handleCloseModal}>
          다음으로 이동하기
        </button>
      </dialog>
    </div>
  );
};

export default Modal;
import React, { useState } from "react";
import "./Body.css";

import ItemList from "./ItemList";
import ItemTotal from "./ItemTotal ";
import ItemInput from "./ItemInput";
import Modal from "./Modal";
import Reward from "./Reward";

function Viewer({ number }) {
  return <div>{number % 2 === 0 ? <h3>짝수</h3> : <h3>홀수</h3>}</div>;
}
const Body = () => {
  const [number, setNumber] = useState(1);

  const onIncrease = () => {
    setNumber(number + 1);
  };
  const onDecrease = () => {
    if (number > 1) {
      setNumber(number - 1);
      onChangePrice(number - 1);
    }
  };

  const itemDateArray = [
    {
      name: "비왈츠 로지 보틀",
      price: 33500,
      number: 1,
    },
  ];

  const [items, setItems] = useState(itemDateArray);

  const onChangePrice = (name, newNumber) => {
    console.log("onChangePrice name : " + name + "number : " + number);

    setItems((prevItems) =>
    prevItems.map((item) =>
      item.name === name ? { ...item, number: newNumber } : item
      )
    );
  };

  const onQuantityChange = (event) => {
    const newNumber = parseInt(event.target.value);
    if (!isNaN(newNumber) && newNumber >= 1) {
      setNumber(newNumber);
      onChangePrice("비왈츠 로지 보틀",newNumber);  // 기본적으로 "비왈츠 로지 보틀"에 대해서 처리
    } else {
      setNumber("");
      onChangePrice(0);
    }
  };
  const handleBlur = () => {
    if (!number || isNaN(number) || number < 1) {
      alert("수량을 올바르게 입력해 주세요.");
      setNumber(1);
      onChangePrice("비왈츠 로지 보틀", 1);
    }
  };
  return (
    <div class="body">
      <div class="purchase-title">프로젝트 이름</div>
      <div id="purchaseWrap">
        <div id="purchase-step">
          <div class="container">
            <div class="circle-container">
              <div class="circle_selected circle">
                <div class="word">리워드 선택</div>
              </div>
            </div>

            <div class="circle-container">
              <div class="circle">
                <div class="word">결제 하기</div>
              </div>
            </div>

            <div class="circle-container">
              <div class="circle">
                <div class="word">결제 완료</div>
              </div>
            </div>
          </div>
          <div class="connector"></div>
        </div>
        <h4>리워드 선택</h4>
        <div class="rewardItemPrice">
          <input type="checkbox" name="reward1" value="33,500" />
          <span>33,500</span>
          &nbsp;원
        </div>
        <div class="rewardItemContent">
          <div class="rewardItemTitle">비왈츠 로지 보틀</div>
          <span class="rewardItemMax">최대 구매 가능 수량 500개</span>
          <div class="rewardItemDesciption">
            14%할인 39,000원 - 33,500원
            <br />
            비왈츠 로지 보틀 1병
          </div>
          <div class="rewardDelivery">
            <img src=""></img>
            <span>배송비 3,000원</span>
            <span class="rewardDeliveryDivide"> | </span>
            <span>2023년 09월 중순 리워드 제공 예정</span>
            <ul>
              <li class="rewardItem">
                <div class="rewardCardName">
                  비왈츠 로지 보틀
                  <button type="button" class="rewardCardCancel">
                    x
                  </button>
                </div>
                <div class="rewardCardContent">
                  <div class="ItemQuantityContainer">
                    <button onClick={onDecrease}> - </button>
                    <input
                      type="number"
                      value={number}
                      name="quantity"
                      min="1"
                      onChange={onQuantityChange}
                      onBlur={handleBlur}
                    />
                    <button onClick={onIncrease}> + </button>
                  </div>
                  <p class="rewardCardPrice"></p>
                </div>
              </li>
            </ul>
          </div>
        </div>

        <h2>{number}</h2>
        <Viewer number={number} />

        <Reward />
        <Modal />
        <div class="circle1"></div>
        <div class="dotted-line"></div>

        <ItemInput
        items={items}
        onChangePrice={onChangePrice}
        number={number}
        onQuantityChange={onQuantityChange}
        onIncrease={onIncrease}
        onDecrease={onDecrease}
        onBlur={handleBlur}
      />
        <hr />
        <ItemList items={items} number={number}  />
        <ItemTotal items={items} number={number} />
      </div>
    </div>
  );
};

export default Body;