Skip to content

Commit a773baf

Browse files
committed
feat: 할 일 추가하기 기능 개발
1 parent ec1ba8a commit a773baf

File tree

5 files changed

+56
-7
lines changed

5 files changed

+56
-7
lines changed

src/actions/add-task.action.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"use server";
2+
3+
import { ActionState } from "@/types";
4+
import { revalidateTag } from "next/cache";
5+
6+
export default async function addTaskAction(
7+
prevData: ActionState,
8+
formData: FormData
9+
): Promise<ActionState> {
10+
const name = formData.get("name")?.toString();
11+
12+
if (!name) return { status: false, error: "할 일을 입력해주세요" };
13+
14+
try {
15+
const response = await fetch(`${process.env.NEXT_API_URL}/items`, {
16+
method: "POST",
17+
headers: {
18+
"Content-Type": "application/json",
19+
},
20+
body: JSON.stringify({ name }),
21+
});
22+
23+
if (!response.ok) return { status: false, error: response.statusText };
24+
25+
revalidateTag("todo");
26+
27+
return { status: true, error: "" };
28+
} catch (error) {
29+
return { status: true, error: `할 일 등록에 실패했습니다. ${error}` };
30+
}
31+
}

src/components/addTask/taskbar.module.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
justify-content: center;
3636
align-items: center;
3737
gap: 4px;
38+
cursor: pointer;
3839
}
3940

4041
.writing_task {

src/components/addTask/taskbar.tsx

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,32 @@
22

33
import Image from "next/image";
44
import styles from "./taskbar.module.css";
5-
import { ChangeEvent, useState } from "react";
5+
import { ChangeEvent, useActionState, useEffect, useState } from "react";
66
import plus from "../../../public/plus.svg";
77
import plusWhite from "../../../public/plus_white.svg";
8+
import addTaskAction from "@/actions/add-task.action";
89

910
export default function Taskbar() {
1011
const [task, setTask] = useState("");
12+
const [state, formAction, isPending] = useActionState(addTaskAction, {
13+
status: true,
14+
error: "",
15+
});
16+
1117
const onChangeTask = (e: ChangeEvent<HTMLInputElement>) => {
1218
setTask(e.target.value);
1319
};
1420

21+
useEffect(() => {
22+
if (state && !state.status) alert(state.error);
23+
setTask("");
24+
}, [state]);
25+
1526
return (
16-
<form>
27+
<form action={formAction}>
1728
<div className={styles.taskbar_box}>
1829
<input
30+
name="name"
1931
className={styles.taskbar}
2032
placeholder="할 일을 입력해주세요"
2133
onChange={onChangeTask}
@@ -26,13 +38,14 @@ export default function Taskbar() {
2638
? `${styles.add_btn} ${styles.writing_task}`
2739
: styles.add_btn
2840
}
41+
disabled={isPending ? true : false}
2942
>
3043
<Image
3144
src={task !== "" ? plusWhite : plus}
3245
width={16}
3346
height={16}
3447
alt="추가이미지"
35-
/>
48+
/>{" "}
3649
추가하기
3750
</button>
3851
</div>

src/components/todo/todoList.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ import emptyDone from "../../../public/empty_done.png";
77
import TodoSection from "./todo-section";
88

99
async function getAllTodoList() {
10-
const response = await fetch(
11-
`${process.env.NEXT_API_URL}/fe-18-sprint9/items`,
12-
{ next: { tags: ["todo"] } }
13-
);
10+
const response = await fetch(`${process.env.NEXT_API_URL}/items`, {
11+
next: { tags: ["todo"] },
12+
});
1413

1514
if (!response.ok) console.error(response.statusText);
1615

src/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,8 @@ export interface TodoSectionProps {
1919
imgAlt: string;
2020
emptyMsg: ReactNode;
2121
}
22+
23+
export interface ActionState {
24+
status: boolean;
25+
error: string;
26+
}

0 commit comments

Comments
 (0)