[React] 코딩 타자 연습 사이트 만들기 (15) - 결과 모달 창으로 출력

Maple·2024년 10월 30일
0

코드보기 : https://github.com/maplesyrup0423/DevTyper

결과 모달 창으로 출력

결과를 도달 창으로 출력하고 "다음"버튼을 눌러 새로고침된 코드 연습을 이어서 할 수 있도록 구현

1. 모달 관리하는 상태, 함수 추가

 const [isModalOpen, setIsModalOpen] = useState(false); // 모달 열림 상태 추가

 const closeModal = () => {
    setIsModalOpen(false); // 모달 닫기 함수
  };

2. 타이핑 완료시 모달 열기

setIsModalOpen(true);추가

  // 타이핑 완료 및 정확도, WPM 계산
  useEffect(() => {
    const cleanedCodeToType = codeToType.replace(/\s+/g, " ").trim();

    if (userInput.length >= cleanedCodeToType.length && userInput.length > 0) {
      const endTime = new Date().getTime();
      setIsFinished(true);

      const timeTaken = (endTime - startTime) / 1000 / 60; // 분 단위 시간
      const correctChars = userInput
        .split("")
        .filter((char, index) => char === cleanedCodeToType[index]).length;

      // 정확도 계산
      const accuracy = (
        (correctChars / cleanedCodeToType.length) *
        100
      ).toFixed(2);
      setAccuracy(accuracy);

      // 총 입력한 글자 수 기준 WPM 계산
      const wpm = (userInput.length / 5 / (timeTaken / 60)).toFixed(2); // 5글자 = 1 단어 기준
      setWpm(wpm);

      // 기록을 로컬 스토리지에 저장
      saveTypingRecord(timeTaken.toFixed(1), accuracy, wpm);

      // 타이핑 완료 시 모달 열기
      setIsModalOpen(true);
    }
  }, [userInput, codeToType, startTime]);

2. 모달 디자인

 {/* 타이핑 완료 모달 */}
      {isModalOpen && (
        <div className="modal">
          <div className="modal-content">
            <span className="close" onClick={closeModal}>
              &times;
            </span>
            <p>소요 시간: {currentTime}</p>
            <p>정확도: {accuracy}%</p>
            <p>속도: {wpm} WPM</p>
            <button
              onClick={() => {
                refreshCodeSnippet();
                closeModal();
              }}
            >
              다음
            </button>
          </div>
        </div>
      )}
/* 모달 배경 스타일 */
.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(255, 255, 255, 0.3); /* 반투명 흰색 배경 */
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

/* 모달 내용 스타일 */
.modal-content {
  background-color: #000; /* 검은색 배경 */
  padding: 20px;
  border: 1px solid #4caf50; /* 초록색 테두리 */
  border-radius: 10px;
  color: white;
  width: 300px;
  text-align: center;
  position: relative;
}

/* 닫기 버튼 스타일 */
.close {
  position: absolute;
  top: 10px;
  right: 10px;
  font-size: 18px;
  color: #4caf50;
  font-size: 24px;
  font-weight: bold;
  cursor: pointer;
}

0개의 댓글