Skip to content

Commit

Permalink
feat : API 연결
Browse files Browse the repository at this point in the history
  • Loading branch information
moana16 committed Jul 18, 2024
1 parent 438551e commit 0ff846d
Show file tree
Hide file tree
Showing 12 changed files with 78 additions and 58 deletions.
5 changes: 3 additions & 2 deletions src/components/todo/RecentTodoList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { getLocalStorage, StorageKeys } from 'src/utils/localStorage';
export default function RecentTodoList() {
const recentTodoList: RecentTodo[] = getLocalStorage(StorageKeys.recentTodo) ?? [];

return recentTodoList.map((recentTodo: RecentTodo) => (
<div key={recentTodo.id}>{recentTodo.title}</div>
return recentTodoList.map((recentTodo: RecentTodo, index:number) => (
// eslint-disable-next-line react/no-array-index-key
<div key={`${recentTodo.todoId}-${index}`}>{recentTodo.title}</div>
));
}
2 changes: 1 addition & 1 deletion src/components/todo/TodoHistory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface TodoHistoryProps {
export default function TodoHistory({ history }: TodoHistoryProps) {
return (
<div>
{history.todo.title}
{history.title}
{history.status}
</div>
);
Expand Down
5 changes: 3 additions & 2 deletions src/components/todo/TodoHistoryList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { TodoHistory as TodoHistoryType } from 'src/types/todo';
export default function TodoHistoryList() {
const { histories } = useGetTodoHistoryList();

return histories.map((history: TodoHistoryType) => (
<TodoHistory key={history.id} history={history} />
return histories.map((history: TodoHistoryType, index:number) => (
// eslint-disable-next-line react/no-array-index-key
<TodoHistory key={`${history.todoId}-${index}`} history={history} />
));
}
4 changes: 2 additions & 2 deletions src/components/todo/TodoList.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import TodoItem from 'src/components/todo/TodoItem';
import TodoItem from 'src/hooks/todo/TodoItem';
import useGetTodoList from 'src/hooks/todo/useGetTodoList';
import type { TodoItem as TodoItemType } from 'src/types/todo';

export default function TodoList() {
const { todos } = useGetTodoList();

return todos.map((todoItem: TodoItemType) => <TodoItem key={todoItem.id} todoItem={todoItem} />);
return todos.map((todoItem: TodoItemType) => <TodoItem key={todoItem.todoId} todoItem={todoItem} />);
}
8 changes: 7 additions & 1 deletion src/constants/api.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
const enum API {}
const BASE_URL = 'http://dating.batro.org:4000/v1/todo';

const enum API {
TODOS = `${BASE_URL}/todos`,
SORT_TODO = `${BASE_URL}/todos/sort`,
TODO_HISTORIES = `${BASE_URL}/histories`,
}

export default API;
24 changes: 15 additions & 9 deletions src/components/todo/todoItem.tsx → src/hooks/todo/TodoItem.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useEffect, useState } from 'react';
import { TodoItem as TodoItemType } from 'src/types/todo';
import { useEffect, useMemo, useState } from 'react';
import useLongPress from 'src/hooks/useLongPress';
import ActionButton from 'src/components/common/ActionButton';
import useDeleteTodo from 'src/hooks/todo/useDeleteTodo';
import useUpdateTodo from 'src/hooks/todo/useUpdateTodo';
import ActionButton from 'src/components/common/ActionButton';
import { TodoItem as TodoItemType } from 'src/types/todo';

interface TodoItemProps {
todoItem: TodoItemType;
Expand All @@ -13,28 +13,34 @@ function TodoItem({ todoItem }: TodoItemProps) {
const { mutate: deleteTodo } = useDeleteTodo();
const { mutate: updateTodo } = useUpdateTodo();

const { id, title, registerDate } = todoItem;
const { todoId, title, registerDate } = todoItem;

const [text, setText] = useState<string>(title);
useEffect(() => setText(todoItem.title), [todoItem]);

const [isEditable, setIsEditable] = useState<boolean>(false);
const longPressRef = useLongPress(() => setIsEditable(true));

const handleDelete = () => deleteTodo(id);
const handleDelete = () => deleteTodo(todoId);
const handleUpdate = () => updateTodo(todoItem, { onSuccess: () => setIsEditable(true) });

const day = useMemo(() => {
const date = new Date(registerDate);
return `${date.getFullYear()}-${date.getMonth()}-${date.getDate()}`;
}, [registerDate]);

return (
<div className="flex justify-between items-center w-full gap-2" ref={longPressRef}>
<div className="bg-white px-3 py-1 h-10 rounded-xl w-full flex justify-between">
<div className="flex justify-between items-center w-max gap-2" ref={longPressRef}>
<div className="bg-white px-3 py-1 h-10 rounded-xl w-full flex justify-between items-center">
<input
disabled={!isEditable}
value={text}
onChange={({ target: { value } }) => setText(value)}
className="bg-transparent"
/>
{registerDate.toISOString()}

<p className="w-max">
{day}
</p>
</div>
{isEditable ? (
<ActionButton label="수정" onClick={handleUpdate} />
Expand Down
20 changes: 16 additions & 4 deletions src/hooks/todo/useCreateTodo.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,30 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { RecentTodo, TodoItem } from 'src/types/todo';
import API from 'src/constants/api';
import { RecentTodo } from 'src/types/todo';
import { getLocalStorage, setLocalStorage, StorageKeys } from 'src/utils/localStorage';

export default function useCreateTodo() {
const queryClient = useQueryClient();

const mutation = useMutation({
mutationFn: (text: string) => Promise.resolve({ id: 3, title: text, registerDate: new Date() }),
onSuccess: (todo: TodoItem) => {
mutationFn: async (title: string) => {
await fetch(API.TODOS, {
method: 'POST',
body: JSON.stringify({ title }),
});
},
onSuccess: () => {
const todo = {
todoId: 5,
title: '임시 최근 생성된 투두',
registerDate: new Date('2023-02-13'),
};
const todos: RecentTodo[] = getLocalStorage(StorageKeys.recentTodo) ?? [];
const newTodos: RecentTodo[] = [...todos.slice(-4), todo];
setLocalStorage(StorageKeys.recentTodo, newTodos);

queryClient.invalidateQueries({ queryKey: [['todos'], ['todos-histories']] });
queryClient.invalidateQueries({ queryKey: ['todos'] });
queryClient.invalidateQueries({ queryKey: ['todos-histories'] });
},
});

Expand Down
11 changes: 9 additions & 2 deletions src/hooks/todo/useDeleteTodo.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import API from 'src/constants/api';

export default function useDeleteTodo() {
const queryClient = useQueryClient();

const mutation = useMutation({
mutationFn: (id: number) => Promise.resolve(id),
mutationFn: async (todoId: number) => {
await fetch(API.TODOS, {
method: 'DELETE',
body: JSON.stringify({ todoId }),
});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [['todos'], ['todos-histories']] });
queryClient.invalidateQueries({ queryKey: ['todos'] });
queryClient.invalidateQueries({ queryKey: ['todos-histories'] });
},
});

Expand Down
30 changes: 5 additions & 25 deletions src/hooks/todo/useGetTodoHistoryList.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,13 @@
import { useSuspenseQuery } from '@tanstack/react-query';
import { TodoHistory } from 'src/types/todo';

const mockHistories: TodoHistory[] = [
{
id: 1,
updatedDate: new Date('2022-02-02'),
todo: {
id: 1,
title: 'string',
registerDate: new Date('2022-02-02'),
},
status: '등록',
},
{
id: 2,
updatedDate: new Date('2022-02-02'),
todo: {
id: 1,
title: 'string',
registerDate: new Date('2022-02-02'),
},
status: '수정',
},
];
import API from 'src/constants/api';

export default function useGetTodoHistoryList() {
const { data: histories } = useSuspenseQuery({
queryKey: ['todos-histories'],
queryFn: () => Promise.resolve(mockHistories),
queryFn: async () => {
const response = await fetch(API.TODO_HISTORIES);
return (await response.json()).data.todoHistories;
},
});

return { histories };
Expand Down
9 changes: 6 additions & 3 deletions src/hooks/todo/useGetTodoList.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { useSuspenseQuery } from '@tanstack/react-query';
import { TodoItem } from 'src/types/todo';
import API from 'src/constants/api';

const mockTodos: TodoItem[] = [{ id: 1, title: 'string', registerDate: new Date('2022-02-02') }];
// const mockTodos: TodoItem[] = [{ id: 1, title: 'string', registerDate: new Date('2022-02-02') }];

export default function useGetTodoList() {
const { data: todos } = useSuspenseQuery({
queryKey: ['todos'],
queryFn: () => Promise.resolve(mockTodos),
queryFn: async () => {
const response = await fetch(API.TODOS);
return (await response.json()).data.todos;
},
});

return { todos };
Expand Down
11 changes: 9 additions & 2 deletions src/hooks/todo/useUpdateTodo.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
import { useMutation, useQueryClient } from '@tanstack/react-query';
import API from 'src/constants/api';
import { TodoItem } from 'src/types/todo';

export default function useUpdateTodo() {
const queryClient = useQueryClient();

const mutation = useMutation({
mutationFn: (todo: TodoItem) => Promise.resolve(todo),
mutationFn: async (todo: TodoItem) => {
await fetch(API.TODOS, {
method: 'PUT',
body: JSON.stringify({ ...todo }),
});
},
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [['todos'], ['todos-histories']] });
queryClient.invalidateQueries({ queryKey: ['todos'] });
queryClient.invalidateQueries({ queryKey: ['todos-histories'] });
},
});

Expand Down
7 changes: 2 additions & 5 deletions src/types/todo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ import { Dispatch } from 'react';
export type TodoStatus = '수정' | '삭제' | '등록';

export interface TodoItem {
id: number;
todoId: number;
title: string;
registerDate: Date;
}

export interface TodoHistory {
id: number;
updatedDate: Date;
todo: TodoItem;
export interface TodoHistory extends TodoItem {
status: TodoStatus;
}

Expand Down

0 comments on commit 0ff846d

Please sign in to comment.