79 lines
3.7 KiB
JavaScript
79 lines
3.7 KiB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
import { useState, useEffect } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { DynamicForm } from "@/components/DynamicForm";
|
|
import { getFeedbackFields, createFeedback } from "@/services/feedback";
|
|
import { ErrorDisplay } from "@/components/ErrorDisplay";
|
|
import { Separator } from "@/components/ui/separator";
|
|
export function FeedbackCreatePage() {
|
|
const navigate = useNavigate();
|
|
const [fields, setFields] = useState([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(null);
|
|
const [submitMessage, setSubmitMessage] = useState(null);
|
|
// TODO: projectId와 channelId는 URL 파라미터나 컨텍스트에서 가져와야 합니다.
|
|
const projectId = "1";
|
|
const channelId = "4";
|
|
useEffect(() => {
|
|
const fetchFields = async () => {
|
|
try {
|
|
setLoading(true);
|
|
const fieldsData = await getFeedbackFields(projectId, channelId);
|
|
// 사용자에게 보여주지 않을 필드 목록
|
|
const hiddenFields = ["id", "createdAt", "updatedAt", "issues"];
|
|
const processedFields = fieldsData
|
|
.filter((field) => !hiddenFields.includes(field.id))
|
|
.map((field) => {
|
|
// 'contents' 필드를 항상 textarea로 처리
|
|
if (field.id === "contents") {
|
|
return { ...field, type: "textarea" };
|
|
}
|
|
return field;
|
|
});
|
|
setFields(processedFields);
|
|
}
|
|
catch (err) {
|
|
if (err instanceof Error) {
|
|
setError(err.message);
|
|
}
|
|
else {
|
|
setError("알 수 없는 오류가 발생했습니다.");
|
|
}
|
|
}
|
|
finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
fetchFields();
|
|
}, [projectId, channelId]);
|
|
const handleSubmit = async (formData) => {
|
|
try {
|
|
setError(null);
|
|
setSubmitMessage(null);
|
|
const requestData = {
|
|
...formData,
|
|
issueNames: [],
|
|
};
|
|
await createFeedback(projectId, channelId, requestData);
|
|
setSubmitMessage("피드백이 성공적으로 등록되었습니다! 곧 목록으로 돌아갑니다.");
|
|
// 2초 후 목록 페이지로 이동
|
|
setTimeout(() => {
|
|
navigate(`/projects/${projectId}/channels/${channelId}/feedbacks`);
|
|
}, 2000);
|
|
}
|
|
catch (err) {
|
|
if (err instanceof Error) {
|
|
setError(err.message);
|
|
}
|
|
else {
|
|
setError("피드백 등록 중 알 수 없는 오류가 발생했습니다.");
|
|
}
|
|
throw err;
|
|
}
|
|
};
|
|
if (loading) {
|
|
return _jsx("div", { children: "\uD3FC\uC744 \uBD88\uB7EC\uC624\uB294 \uC911..." });
|
|
}
|
|
return (_jsxs("div", { className: "container mx-auto p-4", children: [_jsxs("div", { className: "space-y-2 mb-6", children: [_jsx("h1", { className: "text-2xl font-bold", children: "\uD53C\uB4DC\uBC31 \uC791\uC131" }), _jsx("p", { className: "text-muted-foreground", children: "\uC544\uB798 \uD3FC\uC744 \uC791\uC131\uD558\uC5EC \uD53C\uB4DC\uBC31\uC744 \uC81C\uCD9C\uD574\uC8FC\uC138\uC694." })] }), _jsx(Separator, {}), _jsxs("div", { className: "mt-6", children: [_jsx(DynamicForm, { fields: fields, onSubmit: handleSubmit }), error && _jsx(ErrorDisplay, { message: error }), submitMessage && (_jsx("div", { className: "mt-4 p-3 bg-green-100 text-green-800 rounded-md", children: submitMessage }))] })] }));
|
|
}
|