[TIL/React] 2023/04/24

원민관·2023년 4월 24일
0

[TIL]

목록 보기
61/159

src/App.js

import React, { useState } from "react";
import InputSection from "./components/InputSection";
import TodoSection from "./components/TodoSection";
import CompleteSection from "./components/CompleteSection";
import styled from "styled-components";
import { createGlobalStyle } from "styled-components";

const GlobalStyle = createGlobalStyle`
  body {
    background: #d0e3ed;
    opacity: 0.9; 
  }
`;

const inputArray = ["title", "subTitle", "desc"];

function App() {
  const [inputValue, setInputValue] = useState({
    title: "",
    subTitle: "",
    desc: "",
    isDone: false,
  });
  const [editValue, setEditValue] = useState({
    title: "",
    subTitle: "",
    desc: "",
    isDone: false,
  });
  const [todos, setTodos] = useState([]);
  const [id, setId] = useState("");

  const noCompleteArray = todos.filter((todo) => todo?.isDone === false);
  const completeArray = todos.filter((todo) => todo?.isDone === true);

  const handleInputValue = (event) => {
    const { value, name } = event?.target;
    setInputValue((prev) => {
      return { ...prev, [name]: value };
    });
  };
  const handleEditValue = (event) => {
    const { value, name } = event?.target;
    setEditValue((prev) => {
      return { ...prev, [name]: value };
    });
  };

  const addButtonClick = () => {
    setTodos((prev) => {
      return [
        ...prev,
        {
          ...inputValue,
          id: `${inputValue?.title} ${inputValue?.subTitle} ${inputValue?.desc}`,
        },
      ];
    });
    setInputValue({ title: "", subTitle: "", desc: "", isDone: false });
  };

  const deleteButtonClick = (id) => {
    setTodos((prev) => {
      return prev?.filter((todo) => todo?.id !== id);
    });
  };

  const completeButtonClick = (id) => {
    let newArray = todos?.map((todo) =>
      todo?.id === id ? { ...todo, isDone: true } : todo
    );
    setTodos(newArray);
  };

  const editButtonClick = (id) => {
    setId(id);
    const editTodo = todos.find((todo) => todo?.id === id);
    setEditValue(editTodo);
  };
  const saveButtonClick = (id) => {
    setTodos((prev) => {
      return [...prev]?.map((todo) => (todo?.id === id ? editValue : todo));
    });
    setId("");
    setEditValue({
      title: "",
      subTitle: "",
      desc: "",
      isDone: false,
    });
  };
  const cancelButtonClick = (id) => {
    setId("");
    setEditValue({
      title: "",
      subTitle: "",
      desc: "",
      isDone: false,
    });
  };
  // console.log({ inputValue });
  console.log({ todos });
  return (
    <div>
      <GlobalStyle />
      <InputSection
        inputArray={inputArray}
        inputValue={inputValue}
        handleInputValue={handleInputValue}
        addButtonClick={addButtonClick}
      />
      <TodoSection
        noCompleteArray={noCompleteArray}
        editButtonClick={editButtonClick}
        completeButtonClick={completeButtonClick}
        inputArray={inputArray}
        editValue={editValue}
        handleEditValue={handleEditValue}
        saveButtonClick={saveButtonClick}
        editId={id}
        cancelButtonClick={cancelButtonClick}
        deleteButtonClick={deleteButtonClick}
      />
      <CompleteSection
        completeArray={completeArray}
        deleteButtonClick={deleteButtonClick}
      />
    </div>
  );
}

export default App;

src/components/InputSection.js

import React from "react";
import styled from "styled-components";

const InputBorder = styled.div`
 margin: 40px;
 border: 1px solid skyblue;
 border-radius: 20px;
 padding: 10px;
 background-color: white;
`;

const InputTitle = styled.h1`
 text-align: center;
`;
const InputMain = styled.div`
 display: flex;
 flex-direction: column;
`;
const InputTodo = styled.div`
 display: flex;
 justify-content: center;
 margin-bottom: 3px;
`;
const ButtonWrap = styled.div`
 text-align: center;
`;
const AddButton = styled.button`
 background-color: skyblue;
 color: white;
 border-radius: 5px;
 border: none;
 cursor: pointer;
 &:hover {
   background-color: dodgerblue;
 }
`;
const InputInput = styled.input`
 border-radius: 3px;
 padding: 4px;
 width: 200px;
`;

const InputSection = ({
 inputArray,
 inputValue,
 handleInputValue,
 addButtonClick,
}) => {
 return (
   <InputBorder>
     <InputTitle>Todo List 📝</InputTitle>
     {/* Input & Add Button Field */}
     <InputMain>
       {inputArray?.map((name, idx) => {
         return (
           <InputTodo key={idx}>
             <InputInput
               name={name}
               value={inputValue?.[name]}
               onChange={handleInputValue}
               placeholder={name}
             />
           </InputTodo>
         );
       })}

       <ButtonWrap>
         <AddButton onClick={addButtonClick}>Add</AddButton>
       </ButtonWrap>
     </InputMain>
   </InputBorder>
 );
};

export default InputSection;

src/components/TodoSection.js

import React from "react";
import styled from "styled-components";
const TodoTitle = styled.h2`
  text-align: center;
`;

const TodoSection = ({
  noCompleteArray,
  editButtonClick,
  completeButtonClick,
  inputArray,
  editValue,
  handleEditValue,
  saveButtonClick,
  editId,
  cancelButtonClick,
  deleteButtonClick,
}) => {
  return (
    <div>
      <TodoTitle>Todo 👨‍💻</TodoTitle>
      {/* Todo & {(Edit(save, cancel), Complete, Delete) Button Field} */}
      {noCompleteArray.map((todo) => {
        return (
          <div key={todo?.id}>
            {todo?.id === editId ? (
              <div>
                {inputArray?.map((name, idx) => {
                  return (
                    <div key={idx}>
                      <span>{name}</span>
                      <input
                        name={name}
                        value={editValue?.[name]}
                        onChange={handleEditValue}
                      />
                    </div>
                  );
                })}
                <button onClick={() => saveButtonClick(todo?.id)}>Save</button>
                <button onClick={() => cancelButtonClick(todo?.id)}>
                  Cancel
                </button>
              </div>
            ) : (
              <div>
                <div>
                  <button onClick={() => editButtonClick(todo?.id)}>
                    Edit
                  </button>
                  <button onClick={() => completeButtonClick(todo?.id)}>
                    Complete
                  </button>
                  <button onClick={() => deleteButtonClick(todo?.id)}>
                    Delete
                  </button>
                </div>
                <div>
                  <p>Title: {todo?.title}</p>
                  <p>SubTitle: {todo?.subTitle}</p>
                  <p>Desc: {todo?.desc}</p>
                </div>
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
};

export default TodoSection;

src/components/CompleteSection.js

import React from "react";
import styled from "styled-components";

const CompleteTitle = styled.h2`
  text-align: center;
`;

const CompleteSection = ({ completeArray, deleteButtonClick }) => {
  return (
    <div>
      <CompleteTitle>Complete Todo 🔥</CompleteTitle>
      {/* Complete Todo & Delete Button Field */}
      {completeArray.map((todo) => {
        return (
          <div key={todo?.id}>
            <div>
              <button onClick={() => deleteButtonClick(todo?.id)}>
                Delete
              </button>
            </div>
            <div>
              <p>Title: {todo?.title}</p>
              <p>SubTitle: {todo?.subTitle}</p>
              <p>Desc: {todo?.desc}</p>
            </div>
          </div>
        );
      })}
    </div>
  );
};

export default CompleteSection;

현재까지의 스타일링 (styled-components)

내일은 DeepDive를 읽고 정리하도록 하자! 화이팅!

profile
Write a little every day, without hope, without despair ✍️

0개의 댓글