Add todo 리스트 관리 기능 구현
All checks were successful
Build And Test / build-and-push (push) Successful in 1m36s

This commit is contained in:
2025-05-18 23:38:52 +09:00
parent 921359ad71
commit 8cbfe4a864
11 changed files with 532 additions and 4 deletions

View File

@ -0,0 +1,124 @@
import React, { useState } from "react";
import todoApi from "../../api/todoApi";
const TodoForm = ({ onTaskCreated }) => {
const [formData, setFormData] = useState({
title: "",
description: "",
due_date: "",
tags: "",
});
const [expanded, setExpanded] = useState(false);
const handleChange = (e) => {
setFormData((prev) => ({
...prev,
[e.target.name]: e.target.value,
}));
};
const handleSubmit = async (e) => {
e.preventDefault();
const tagList =
formData.tags.trim() !== ""
? formData.tags.split(",").map((tag) => tag.trim())
: [];
try {
await todoApi.post("/api/todo/tasks/", {
title: formData.title,
description: formData.description,
due_date: formData.due_date === "" ? null : formData.due_date,
tags: tagList,
});
setFormData({ title: "", description: "", due_date: "", tags: "" });
setExpanded(false);
onTaskCreated();
} catch (err) {
console.error("등록 실패:", err.response?.data || err.message);
alert("등록 실패: " + JSON.stringify(err.response?.data));
}
};
const handleCancel = () => {
setFormData({ title: "", description: "", due_date: "", tags: "" });
setExpanded(false);
};
return (
<form
onSubmit={handleSubmit}
className="bg-white p-4 rounded-lg shadow mb-6 border border-gray-200"
>
<input
type="text"
name="title"
value={formData.title}
onFocus={() => setExpanded(true)}
onChange={handleChange}
placeholder=" 작업 추가하기..."
required
className="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-300 mb-2"
/>
{expanded && (
<>
<textarea
name="description"
value={formData.description}
onChange={handleChange}
placeholder="설명 (선택)"
className="w-full px-3 py-2 border rounded-md resize-none focus:outline-none focus:ring-2 focus:ring-blue-300 mb-2"
rows="2"
/>
<div className="flex gap-4 mb-2">
<div className="flex-1">
<label className="block text-sm text-gray-600 mb-1">📅 마감일</label>
<input
type="date"
name="due_date"
value={formData.due_date}
onChange={handleChange}
className="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-300"
/>
</div>
<div className="flex-1">
<label className="block text-sm text-gray-600 mb-1">🏷 태그</label>
<input
type="text"
name="tags"
value={formData.tags}
onChange={handleChange}
placeholder="예: 중요, 오늘, 업무"
className="w-full px-3 py-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-300"
/>
</div>
</div>
<div className="flex justify-end space-x-2">
<button
type="button"
onClick={handleCancel}
className="px-4 py-2 border border-gray-300 rounded-md text-gray-600 hover:bg-gray-100 transition"
>
취소
</button>
<button
type="submit"
className="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600 transition"
>
등록
</button>
</div>
</>
)}
</form>
);
};
export default TodoForm;