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를 읽고 정리하도록 하자! 화이팅!