[TIL] CRA, Vite, Tailwind css

곽재훈·2024년 5월 13일
1
post-thumbnail

여는 글

오늘은 드디어 React 개인과제 돌입!
오전에는 거의 CRA랑 Vite, Tailwind css를 설치해보는데 시간을 다 보냈다. 캠프 전에 경험해본 것이 딱 javascript였기 때문에 React고 Tailwind고 죄다 처음이여서 엄청 헤맸다.

아직 컴포넌트 분리나 이런 것들이 어려워서 일단 완성해보고 컴포넌트 분리도 해 볼듯!

import PropTypes from "prop-types";
import { useState } from "react";

const ToDosTitle = ({ title }) => {
  return <h2 className="text-3xl font-bold py-2">{title}</h2>;
};

ToDosTitle.propTypes = {
  title: PropTypes.string.isRequired,
};

const ToDo = ({ id, title, body, isDone, setToDos }) => {
  return (
    <div className=" h-32 w-48 p-2 ml-8 bg-white rounded-2xl">
      <div className="flex justify-between text-xs border-black border-b-2 pb-2">
        <p className={"flex justify-center items-center text-lg font-black"}>
          {isDone ? "완료" : "진행중"}
        </p>
        <button
          className={"px-2 py-1 border-2 border-black rounded-lg"}
          onClick={() => {
            setToDos((toDos) => {
              return toDos.map((toDo) => {
                if (toDo.id === id) {
                  const newToDo = { ...toDo };
                  newToDo.isDone = !newToDo.isDone;
                  return newToDo;
                }
                return toDo;
              });
            });
          }}
        >
          {isDone ? "취소" : "완료"}
        </button>
        <button
          className={
            " bg-red-800 text-white px-2 py-1 rounded-lg border-2 border-black"
          }
          onClick={() => {
            setToDos((toDos) => {
              return toDos.filter((toDo) => {
                if (toDo.id === id) {
                  return false;
                }
                return true;
              });
            });
          }}
        >
          삭제
        </button>
      </div>
      <h3 className={isDone ? "text-lg line-through" : "text-lg no-underline"}>
        {title}
      </h3>
      <p className={isDone ? "text-sm line-through" : "text-sm no-underline"}>
        {body}
      </p>
    </div>
  );
};

ToDo.propTypes = {
  setToDos: PropTypes.func.isRequired,
  title: PropTypes.string.isRequired,
  body: PropTypes.string.isRequired,
  isDone: PropTypes.bool.isRequired,
  id: PropTypes.number.isRequired,
};

const App = () => {
  const [toDoTitle, setToDoTitle] = useState("");
  const [toDoBody, setToDoBody] = useState("");
  const [toDos, setToDos] = useState([]);
  const template = {
    toDoTitle: "제목을 입력해주세요",
    toDoBody: "내용을 입력해주세요",
  };

  console.log("to do title: ", toDoTitle, "to do body: ", toDoBody);
  console.log("current to dos", toDos);

  return (
    <article className=" max-w-[1200px] min-w-[800px] h-[600px] bg-blue-200">
      <form
        className=" flex flex-col justify-center items-center h-1/3"
        onSubmit={(e) => {
          e.preventDefault();
          const newToDo = {
            id: new Date().getTime(),
            title: toDoTitle,
            body: toDoBody,
            isDone: false,
          };
          setToDos([newToDo, ...toDos]);
          setToDoTitle("");
          setToDoBody("");
        }}
      >
        <label>할 일</label>
        <input
          type="text"
          onChange={(e) => {
            setToDoTitle(e.target.value);
          }}
          value={toDoTitle}
          placeholder={template.toDoTitle}
        />
        <label>내용</label>
        <input
          type="text"
          onChange={(e) => {
            setToDoBody(e.target.value);
          }}
          value={toDoBody}
          placeholder={template.toDoBody}
        />
        <button>Add To Do</button>
      </form>
      <section className="h-1/3 bg-yellow-600  box-border">
        <ToDosTitle title="진행중인 목록" />
        <ul className="flex justify-start items-center">
          {toDos
            .filter((toDo) => {
              return toDo.isDone === false;
            })
            .map((toDo) => {
              const { id, title, body, isDone } = toDo;
              return (
                <li className="h-full" key={id}>
                  <ToDo
                    id={id}
                    title={title}
                    body={body}
                    isDone={isDone}
                    setToDos={setToDos}
                  />
                </li>
              );
            })}
        </ul>
      </section>
      <section className="h-1/3 bg-yellow-300 flex flex-col items-start">
        <ToDosTitle title="완료된 목록" />
        <ul className="flex justify-start">
          {toDos
            .filter((toDo) => {
              return toDo.isDone === true;
            })
            .map((toDo) => {
              const { id, title, body, isDone } = toDo;
              return (
                <li key={id}>
                  <ToDo
                    id={id}
                    title={title}
                    body={body}
                    isDone={isDone}
                    setToDos={setToDos}
                  />
                </li>
              );
            })}
        </ul>
      </section>
    </article>
  );
};

export default App;
profile
개발하고 싶은 국문과 머시기

1개의 댓글

comment-user-thumbnail
2024년 5월 14일

재훈님 고생하셨어요!!ㅋㅋ

답글 달기

관련 채용 정보