From a5d8ea5c7e502b403c97fc46682673b3ac25e678 Mon Sep 17 00:00:00 2001 From: SalmonTaker Date: Thu, 24 Aug 2023 13:59:18 +0900 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20todo=20api=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 이선근 --- src/apis/todo.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/apis/todo.ts diff --git a/src/apis/todo.ts b/src/apis/todo.ts new file mode 100644 index 0000000..47075a6 --- /dev/null +++ b/src/apis/todo.ts @@ -0,0 +1,25 @@ +import { AuthInstance } from './instance' +import { TodoType } from '../components/TodoList/types' + +export const createTodoRequest = async (todo: string): Promise => { + const { data } = await AuthInstance.post('/todos', { todo }) + return data +} + +export const getTodosRequest = async (): Promise => { + const { data } = await AuthInstance.get('/todos') + return data +} + +export const updateTodoRequest = async ( + id: number, + todo: string, + isCompleted: boolean +): Promise => { + const { data } = await AuthInstance.put(`/todos/${id}`, { todo, isCompleted }) + return data +} + +export const deleteTodoRequest = (id: number) => { + return AuthInstance.delete(`/todos/${id}`) +} From 935ecfe5714b71b949e8bce1c813e91d58be7019 Mon Sep 17 00:00:00 2001 From: SalmonTaker Date: Thu, 24 Aug 2023 14:00:25 +0900 Subject: [PATCH 2/5] =?UTF-8?q?feat:=20todo=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 이선근 --- src/components/TodoItem/TodoItem.tsx | 81 +++++++++++++++++++++++++++ src/components/TodoItem/types.ts | 8 +++ src/components/TodoList/TodoList.tsx | 83 ++++++++++++++++++++++++++++ src/components/TodoList/types.ts | 6 ++ 4 files changed, 178 insertions(+) create mode 100644 src/components/TodoItem/TodoItem.tsx create mode 100644 src/components/TodoItem/types.ts create mode 100644 src/components/TodoList/TodoList.tsx create mode 100644 src/components/TodoList/types.ts diff --git a/src/components/TodoItem/TodoItem.tsx b/src/components/TodoItem/TodoItem.tsx new file mode 100644 index 0000000..2759161 --- /dev/null +++ b/src/components/TodoItem/TodoItem.tsx @@ -0,0 +1,81 @@ +import { useState } from 'react' +import TodoItemProps from './types' + +function TodoItem({ id, todo, isCompleted, updateTodo, deleteTodo }: TodoItemProps) { + const [todoCheck, setTodoCheck] = useState(isCompleted) + const [todoModify, setTodoModify] = useState('') + const [isEditMode, setIsEditMode] = useState(false) + + // TODO의 체크박스가 변경 되었을 때 + const onTodoCheckChanged = () => { + updateTodo(id, todo, !todoCheck) + setTodoCheck(!todoCheck) + } + + // TODO input창의 값이 변경 되었을 때 (수정모드) + const onTodoModifyChanged = (e: React.ChangeEvent) => { + const value = e.target.value + setTodoModify(value) + } + + // 수정 버튼을 눌렀을 때 + const onEditButtonClicked = () => { + setTodoModify(todo) + setIsEditMode(true) + } + + // 취소 버튼을 눌렀을 때 + const onCancelButtonClicked = () => { + setIsEditMode(false) + } + + // 제출 버튼을 눌렀을 때 + const onSubmitButtonClicked = () => { + updateTodo(id, todoModify, isCompleted) + setIsEditMode(false) + } + + // 삭제 버튼을 눌렀을 때 + const onDeleteButtonClicked = () => { + deleteTodo(id) + } + + return ( +
  • + + {isEditMode ? ( + <> + + + + ) : ( + <> + + + + )} +
  • + ) +} + +export default TodoItem diff --git a/src/components/TodoItem/types.ts b/src/components/TodoItem/types.ts new file mode 100644 index 0000000..214d208 --- /dev/null +++ b/src/components/TodoItem/types.ts @@ -0,0 +1,8 @@ +import { TodoType } from '../TodoList/types' + +interface TodoItemProps extends Omit { + updateTodo: (id: number, todo: string, isCompleted: boolean) => void + deleteTodo: (id: number) => void +} + +export default TodoItemProps diff --git a/src/components/TodoList/TodoList.tsx b/src/components/TodoList/TodoList.tsx new file mode 100644 index 0000000..e56524a --- /dev/null +++ b/src/components/TodoList/TodoList.tsx @@ -0,0 +1,83 @@ +import { useState, useEffect } from 'react' + +import TodoItem from '../TodoItem/TodoItem' +import { TodoType } from './types' +import { + createTodoRequest, + getTodosRequest, + updateTodoRequest, + deleteTodoRequest, +} from '../../apis/todo' +import { AxiosError } from 'axios' + +function TodoList() { + const [todos, setTodos] = useState([]) + const [newTodo, setNewTodo] = useState('') + + const createTodo = (todo: string) => { + createTodoRequest(todo) + .then((createdTodo) => { + setTodos((prevTodos) => [...prevTodos, createdTodo]) + setNewTodo('') + }) + .catch((e: AxiosError) => alert(e)) + } + + const getTodo = () => { + getTodosRequest() + .then((todos) => setTodos(todos)) + .catch((e: AxiosError) => alert(e.message)) + } + + const updateTodo = (id: number, todo: string, isCompleted: boolean) => { + updateTodoRequest(id, todo, isCompleted) + .then((updatedTodo) => + setTodos((prevTodos) => + prevTodos.map((prevTodo) => (prevTodo.id === id ? updatedTodo : prevTodo)) + ) + ) + .catch((e: AxiosError) => alert(e.message)) + } + + const deleteTodo = (id: number) => { + deleteTodoRequest(id) + .then(() => setTodos((prevTodos) => prevTodos.filter((prevTodo) => prevTodo.id !== id))) + .catch((e: AxiosError) => alert(e.message)) + } + + useEffect(() => { + getTodo() + }, []) + + return ( +
    +
    + + +
    +
      + {todos.map((todo) => ( + + ))} +
    +
    + ) +} + +export default TodoList diff --git a/src/components/TodoList/types.ts b/src/components/TodoList/types.ts new file mode 100644 index 0000000..563b53d --- /dev/null +++ b/src/components/TodoList/types.ts @@ -0,0 +1,6 @@ +export interface TodoType { + id: number + todo: string + isCompleted: boolean + userId: number +} From af58ded6b44ff9eb8c4916c0a9a1b02fd27610aa Mon Sep 17 00:00:00 2001 From: SalmonTaker Date: Thu, 24 Aug 2023 14:00:32 +0900 Subject: [PATCH 3/5] =?UTF-8?q?feat:=20todo=20=ED=8E=98=EC=9D=B4=EC=A7=80?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: 이선근 --- src/pages/Todo.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/Todo.tsx b/src/pages/Todo.tsx index 511d213..7b5aca4 100644 --- a/src/pages/Todo.tsx +++ b/src/pages/Todo.tsx @@ -1,4 +1,5 @@ import { useNavigate } from 'react-router-dom' +import TodoList from '../components/TodoList/TodoList' function Todo() { const navigate = useNavigate() @@ -6,6 +7,7 @@ function Todo() { return (
    투두리스트 페이지입니다. +