[팀 포트폴리오] [Momentum 클론 웹사이트] 2. 코드 분석 <App.js>

2024. 12. 11. 10:50웹개발 포트폴리오

728x90
반응형
import React, { useState, useEffect } from "react";
import "./App.css";
import { startClock } from "./js/clock";
import { initializeQuotes } from "./js/quotes";
import { initializeWeather } from "./js/weather";
import Background from "./js/background";
import FocusMode from "./jsx/FocusMode";

function App() {
  const [username, setUsername] = useState(null);
  // 사용자의 이름을 저장하는 상태 변수
  const [focusMode, setFocusMode] = useState(false);
  // FocusMode의 활성화 여부를 나타내는 상태 변수
  const [todos, setTodos] = useState([]);
  // 할 일 목록을 저장하는 상태 변수

  useEffect(() => {
    startClock(); // 시계 초기화 (화면 표시를 위해)
    initializeQuotes(); // 명언 초기화 (화면 표시를 위해)
    initializeWeather(); // 날씨 초기화 (화면 표시를 위해)

    const savedUsername = localStorage.getItem("username");
    // 로컬 스토리지에서 username이라는 키 값으로 저장된 값을 가져온다
    if (savedUsername) {
    // 로컬 스토리지에 저장된 사용자 이름이 있다면
      setUsername(savedUsername);
    // 저장된 값을 UI에 표시
    }

    const savedToDos = localStorage.getItem("todos");
    if (savedToDos) {
    // 저장된 todos가 있다면
      setTodos(JSON.parse(savedToDos));
    // 로컬 스토리지에서 가져온 문자열 값을 JS 객체 형태로 변환하여
    // UI에 표시
    }
  }, []);

  // 할 일 목록을 제출하는 함수 (할 일을 추가하고 로컬 스토리지에 저장)
  const handleToDoSubmit = (event) => {
    event.preventDefault();
    // 폼 제출 이벤트의 기본 동작 (새로고침)을 방지
    const todoInput = event.target.elements.todoInput.value.trim();
    // event.target.elements : 폼 내의 모든 입력 필드
    // todoInput : 객체 내의 name = "todoInput"이라는 속성을 가진 요소를 참조
    // 사용자가 입력한 할 일의 텍스트를 가져옴
    // value는 입력 필드의 값을 가져오며, trim()은 텍스트 앞뒤의 공백을 제거
    if (todoInput) {
    // todoInput이 빈 문자열이 아니면 (텍스트를 입력한 경우)
      const newTodo = { id: Date.now(), text: todoInput };
      각 입력값에 고유 id를 Date.now()를 사용하여 부여함
      const updatedTodos = [...todos, newTodo];
      // 업데이트 된 todos
      // 기존 todos 배열에 새로운 todo를 추가하여 배열 생성
      setTodos(updatedTodos);
      // todos 상태를 업데이트
      localStorage.setItem("todos", JSON.stringify(updatedTodos));
      // 로컬 스토리지에 JS 객체를 문자열로 변환하여 저장
      event.target.reset();
      // 폼 입력 필드를 초기화하여 사용자가 입력한 텍스트를 리셋
    }
  };

// 할 일 목록에서 요소를 제거하는 함수
  const handleDeleteToDo = (id) => {
    const updatedTodos = todos.filter((todo) => todo.id !== id);
    // updatedTodos 함수는 todos 배열에서 id가 일치하는 항목만 제거한다
    setTodos(updatedTodos);
    // todos 배열 저장
    localStorage.setItem("todos", JSON.stringify(updatedTodos));
    // 로컬 스토리지에 데이터를 저장하는 메서드
    // JS 배열을 문자열로 변환해 저장
  };

  return (
    <div>
      <div className={focusMode ? "background-blurred" : ""}>
      // 포커스 모드냐에 따라 배경 블러 처리
        <Background />
      </div>
      {username && ( // 로그인 상태에서만 버튼 표시
      <button
        className="focus-mode-toggle-button"
        onClick={() => setFocusMode(!focusMode)}
      >
        {focusMode ? "Exit Focus Mode" : "Enter Focus Mode"}
      </button>
    )}
      {focusMode ? (
        <FocusMode onExit={() => setFocusMode(false)} />
      ) : (
        <>
          <div id="top-section">
            <h2 id="clock">00:00:00</h2>
            {!username ? (
              <form
                id="login-form"
                onSubmit={(e) => {
                  e.preventDefault();
                  const usernameValue = e.target.elements.username.value;
                  setUsername(usernameValue);
                  localStorage.setItem("username", usernameValue);
                }}
              >
                <input
                  type="text"
                  name="username"
                  placeholder="What is your name?"
                  required
                />
                <input type="submit" value="Log In" />
              </form>
            ) : (
              <div>
                <h1 id="greeting">Hello! {username}</h1>
                <button
                  id="logout-button"
                  onClick={() => {
                    localStorage.removeItem("username");
                    setUsername(null);
                  }}
                >
                  Log Out
                </button>
              </div>
            )}
          </div>
          {username && (
            <div id="todo-section">
              <form id="todo-form" onSubmit={handleToDoSubmit}>
                <input
                  type="text"
                  name="todoInput"
                  placeholder="Write a To Do and Press Enter"
                  required
                />
              </form>
              <ul id="todo-list">
                {todos.map((todo) => (
                  <li
                    key={todo.id}
                    onClick={() => handleDeleteToDo(todo.id)}
                    style={{ cursor: "pointer" }}
                  >
                    {todo.text}
                  </li>
                ))}
              </ul>
            </div>
          )}
          <div id="quote">
            <span></span>
            <span></span>
          </div>
          <div id="weather">
            <span></span>
            <span></span>
          </div>
        </>
      )}
    </div>
  );
}

export default App;
728x90
반응형