From a53340e3c198be14e707ce439b7d04ef767ba7ab Mon Sep 17 00:00:00 2001
From: Lectom C Han
Date: Sun, 3 Aug 2025 00:40:25 +0900
Subject: [PATCH] =?UTF-8?q?js=20=EC=9D=98=EC=A1=B4=EC=84=B1=20=EC=A0=9C?=
=?UTF-8?q?=EA=B1=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../{src => }/components/LanguageSelectBox.js | 0
.../src/components/DynamicForm.js | 0
.../src/components/DynamicTable.js | 0
.../src/components/ErrorDisplay.js | 0
.../{ => effort_js}/src/components/Header.js | 0
.../src/components/MainLayout.js | 0
.../src/components/ProjectSelectBox.js | 0
.../src/components/ThemeSelectBox.js | 0
.../src/components/UserProfileBox.js | 0
.../src/components/providers/ThemeProvider.js | 0
.../src/components/ui/button.js | 0
.../src/components/ui/calendar.js | 0
.../{ => effort_js}/src/components/ui/card.js | 0
.../src/components/ui/dropdown-menu.js | 0
.../src/components/ui/input.js | 0
.../src/components/ui/label.js | 0
.../src/components/ui/popover.js | 0
.../src/components/ui/select.js | 0
.../src/components/ui/separator.js | 0
.../src/components/ui/table.js | 0
.../src/components/ui/textarea.js | 0
viewer/{ => effort_js}/src/lib/utils.js | 0
.../src/pages/FeedbackCreatePage.js | 0
.../src/pages/FeedbackDetailPage.js | 0
.../src/pages/FeedbackListPage.js | 0
.../src/pages/IssueViewerPage.js | 0
viewer/{ => effort_js}/src/services/error.js | 0
.../{ => effort_js}/src/services/feedback.js | 2 +-
viewer/{ => effort_js}/src/services/issue.js | 2 +-
.../{ => effort_js}/src/services/project.js | 0
viewer/{ => effort_js/src}/vite.config.js | 0
viewer/src/components/Header.tsx | 14 ++++-
viewer/src/components/MainLayout.tsx | 4 +-
viewer/src/pages/FeedbackCreatePage.tsx | 17 ++++--
viewer/src/pages/FeedbackDetailPage.tsx | 58 +++++++++++--------
viewer/src/pages/FeedbackListPage.tsx | 20 ++++---
viewer/src/services/feedback.ts | 6 ++
viewer/src/store/useSettingsStore.ts | 17 +++++-
viewer/tsconfig.json | 3 +-
viewer/vite.config.ts | 1 +
40 files changed, 96 insertions(+), 48 deletions(-)
rename viewer/{src => }/components/LanguageSelectBox.js (100%)
rename viewer/{ => effort_js}/src/components/DynamicForm.js (100%)
rename viewer/{ => effort_js}/src/components/DynamicTable.js (100%)
rename viewer/{ => effort_js}/src/components/ErrorDisplay.js (100%)
rename viewer/{ => effort_js}/src/components/Header.js (100%)
rename viewer/{ => effort_js}/src/components/MainLayout.js (100%)
rename viewer/{ => effort_js}/src/components/ProjectSelectBox.js (100%)
rename viewer/{ => effort_js}/src/components/ThemeSelectBox.js (100%)
rename viewer/{ => effort_js}/src/components/UserProfileBox.js (100%)
rename viewer/{ => effort_js}/src/components/providers/ThemeProvider.js (100%)
rename viewer/{ => effort_js}/src/components/ui/button.js (100%)
rename viewer/{ => effort_js}/src/components/ui/calendar.js (100%)
rename viewer/{ => effort_js}/src/components/ui/card.js (100%)
rename viewer/{ => effort_js}/src/components/ui/dropdown-menu.js (100%)
rename viewer/{ => effort_js}/src/components/ui/input.js (100%)
rename viewer/{ => effort_js}/src/components/ui/label.js (100%)
rename viewer/{ => effort_js}/src/components/ui/popover.js (100%)
rename viewer/{ => effort_js}/src/components/ui/select.js (100%)
rename viewer/{ => effort_js}/src/components/ui/separator.js (100%)
rename viewer/{ => effort_js}/src/components/ui/table.js (100%)
rename viewer/{ => effort_js}/src/components/ui/textarea.js (100%)
rename viewer/{ => effort_js}/src/lib/utils.js (100%)
rename viewer/{ => effort_js}/src/pages/FeedbackCreatePage.js (100%)
rename viewer/{ => effort_js}/src/pages/FeedbackDetailPage.js (100%)
rename viewer/{ => effort_js}/src/pages/FeedbackListPage.js (100%)
rename viewer/{ => effort_js}/src/pages/IssueViewerPage.js (100%)
rename viewer/{ => effort_js}/src/services/error.js (100%)
rename viewer/{ => effort_js}/src/services/feedback.js (98%)
rename viewer/{ => effort_js}/src/services/issue.js (92%)
rename viewer/{ => effort_js}/src/services/project.js (100%)
rename viewer/{ => effort_js/src}/vite.config.js (100%)
diff --git a/viewer/src/components/LanguageSelectBox.js b/viewer/components/LanguageSelectBox.js
similarity index 100%
rename from viewer/src/components/LanguageSelectBox.js
rename to viewer/components/LanguageSelectBox.js
diff --git a/viewer/src/components/DynamicForm.js b/viewer/effort_js/src/components/DynamicForm.js
similarity index 100%
rename from viewer/src/components/DynamicForm.js
rename to viewer/effort_js/src/components/DynamicForm.js
diff --git a/viewer/src/components/DynamicTable.js b/viewer/effort_js/src/components/DynamicTable.js
similarity index 100%
rename from viewer/src/components/DynamicTable.js
rename to viewer/effort_js/src/components/DynamicTable.js
diff --git a/viewer/src/components/ErrorDisplay.js b/viewer/effort_js/src/components/ErrorDisplay.js
similarity index 100%
rename from viewer/src/components/ErrorDisplay.js
rename to viewer/effort_js/src/components/ErrorDisplay.js
diff --git a/viewer/src/components/Header.js b/viewer/effort_js/src/components/Header.js
similarity index 100%
rename from viewer/src/components/Header.js
rename to viewer/effort_js/src/components/Header.js
diff --git a/viewer/src/components/MainLayout.js b/viewer/effort_js/src/components/MainLayout.js
similarity index 100%
rename from viewer/src/components/MainLayout.js
rename to viewer/effort_js/src/components/MainLayout.js
diff --git a/viewer/src/components/ProjectSelectBox.js b/viewer/effort_js/src/components/ProjectSelectBox.js
similarity index 100%
rename from viewer/src/components/ProjectSelectBox.js
rename to viewer/effort_js/src/components/ProjectSelectBox.js
diff --git a/viewer/src/components/ThemeSelectBox.js b/viewer/effort_js/src/components/ThemeSelectBox.js
similarity index 100%
rename from viewer/src/components/ThemeSelectBox.js
rename to viewer/effort_js/src/components/ThemeSelectBox.js
diff --git a/viewer/src/components/UserProfileBox.js b/viewer/effort_js/src/components/UserProfileBox.js
similarity index 100%
rename from viewer/src/components/UserProfileBox.js
rename to viewer/effort_js/src/components/UserProfileBox.js
diff --git a/viewer/src/components/providers/ThemeProvider.js b/viewer/effort_js/src/components/providers/ThemeProvider.js
similarity index 100%
rename from viewer/src/components/providers/ThemeProvider.js
rename to viewer/effort_js/src/components/providers/ThemeProvider.js
diff --git a/viewer/src/components/ui/button.js b/viewer/effort_js/src/components/ui/button.js
similarity index 100%
rename from viewer/src/components/ui/button.js
rename to viewer/effort_js/src/components/ui/button.js
diff --git a/viewer/src/components/ui/calendar.js b/viewer/effort_js/src/components/ui/calendar.js
similarity index 100%
rename from viewer/src/components/ui/calendar.js
rename to viewer/effort_js/src/components/ui/calendar.js
diff --git a/viewer/src/components/ui/card.js b/viewer/effort_js/src/components/ui/card.js
similarity index 100%
rename from viewer/src/components/ui/card.js
rename to viewer/effort_js/src/components/ui/card.js
diff --git a/viewer/src/components/ui/dropdown-menu.js b/viewer/effort_js/src/components/ui/dropdown-menu.js
similarity index 100%
rename from viewer/src/components/ui/dropdown-menu.js
rename to viewer/effort_js/src/components/ui/dropdown-menu.js
diff --git a/viewer/src/components/ui/input.js b/viewer/effort_js/src/components/ui/input.js
similarity index 100%
rename from viewer/src/components/ui/input.js
rename to viewer/effort_js/src/components/ui/input.js
diff --git a/viewer/src/components/ui/label.js b/viewer/effort_js/src/components/ui/label.js
similarity index 100%
rename from viewer/src/components/ui/label.js
rename to viewer/effort_js/src/components/ui/label.js
diff --git a/viewer/src/components/ui/popover.js b/viewer/effort_js/src/components/ui/popover.js
similarity index 100%
rename from viewer/src/components/ui/popover.js
rename to viewer/effort_js/src/components/ui/popover.js
diff --git a/viewer/src/components/ui/select.js b/viewer/effort_js/src/components/ui/select.js
similarity index 100%
rename from viewer/src/components/ui/select.js
rename to viewer/effort_js/src/components/ui/select.js
diff --git a/viewer/src/components/ui/separator.js b/viewer/effort_js/src/components/ui/separator.js
similarity index 100%
rename from viewer/src/components/ui/separator.js
rename to viewer/effort_js/src/components/ui/separator.js
diff --git a/viewer/src/components/ui/table.js b/viewer/effort_js/src/components/ui/table.js
similarity index 100%
rename from viewer/src/components/ui/table.js
rename to viewer/effort_js/src/components/ui/table.js
diff --git a/viewer/src/components/ui/textarea.js b/viewer/effort_js/src/components/ui/textarea.js
similarity index 100%
rename from viewer/src/components/ui/textarea.js
rename to viewer/effort_js/src/components/ui/textarea.js
diff --git a/viewer/src/lib/utils.js b/viewer/effort_js/src/lib/utils.js
similarity index 100%
rename from viewer/src/lib/utils.js
rename to viewer/effort_js/src/lib/utils.js
diff --git a/viewer/src/pages/FeedbackCreatePage.js b/viewer/effort_js/src/pages/FeedbackCreatePage.js
similarity index 100%
rename from viewer/src/pages/FeedbackCreatePage.js
rename to viewer/effort_js/src/pages/FeedbackCreatePage.js
diff --git a/viewer/src/pages/FeedbackDetailPage.js b/viewer/effort_js/src/pages/FeedbackDetailPage.js
similarity index 100%
rename from viewer/src/pages/FeedbackDetailPage.js
rename to viewer/effort_js/src/pages/FeedbackDetailPage.js
diff --git a/viewer/src/pages/FeedbackListPage.js b/viewer/effort_js/src/pages/FeedbackListPage.js
similarity index 100%
rename from viewer/src/pages/FeedbackListPage.js
rename to viewer/effort_js/src/pages/FeedbackListPage.js
diff --git a/viewer/src/pages/IssueViewerPage.js b/viewer/effort_js/src/pages/IssueViewerPage.js
similarity index 100%
rename from viewer/src/pages/IssueViewerPage.js
rename to viewer/effort_js/src/pages/IssueViewerPage.js
diff --git a/viewer/src/services/error.js b/viewer/effort_js/src/services/error.js
similarity index 100%
rename from viewer/src/services/error.js
rename to viewer/effort_js/src/services/error.js
diff --git a/viewer/src/services/feedback.js b/viewer/effort_js/src/services/feedback.js
similarity index 98%
rename from viewer/src/services/feedback.js
rename to viewer/effort_js/src/services/feedback.js
index 5996da9..0c52058 100644
--- a/viewer/src/services/feedback.js
+++ b/viewer/effort_js/src/services/feedback.js
@@ -1,5 +1,5 @@
// src/services/feedback.ts
-import { handleApiError } from "./error";
+import { handleApiError } from "../../../src/services/error";
// --- API 함수 ---
const getFeedbacksSearchApiUrl = (projectId, channelId) =>
`/api/v2/projects/${projectId}/channels/${channelId}/feedbacks/search`;
diff --git a/viewer/src/services/issue.js b/viewer/effort_js/src/services/issue.js
similarity index 92%
rename from viewer/src/services/issue.js
rename to viewer/effort_js/src/services/issue.js
index eaa253b..0ac14e7 100644
--- a/viewer/src/services/issue.js
+++ b/viewer/effort_js/src/services/issue.js
@@ -1,5 +1,5 @@
// src/services/issue.ts
-import { handleApiError } from "./error";
+import { handleApiError } from "../../../src/services/error";
/**
* 특정 프로젝트의 모든 이슈를 검색합니다.
* @param projectId 프로젝트 ID
diff --git a/viewer/src/services/project.js b/viewer/effort_js/src/services/project.js
similarity index 100%
rename from viewer/src/services/project.js
rename to viewer/effort_js/src/services/project.js
diff --git a/viewer/vite.config.js b/viewer/effort_js/src/vite.config.js
similarity index 100%
rename from viewer/vite.config.js
rename to viewer/effort_js/src/vite.config.js
diff --git a/viewer/src/components/Header.tsx b/viewer/src/components/Header.tsx
index 21ac292..0124925 100644
--- a/viewer/src/components/Header.tsx
+++ b/viewer/src/components/Header.tsx
@@ -1,3 +1,4 @@
+import { cn } from "@/lib/utils";
import { NavLink } from "react-router-dom";
import { ProjectSelectBox } from "./ProjectSelectBox";
import { ThemeSelectBox } from "./ThemeSelectBox";
@@ -10,7 +11,11 @@ const menuItems = [
{ name: "Issue", path: "/issues", type: "issue" },
];
-export function Header() {
+interface HeaderProps {
+ className?: string;
+}
+
+export function Header({ className }: HeaderProps) {
const { projectId, channelId } = useSettingsStore();
const getPath = (type: string, basePath: string) => {
@@ -23,7 +28,12 @@ export function Header() {
const homePath = `/projects/${projectId}`;
return (
-
+
-
-
+
+
diff --git a/viewer/src/pages/FeedbackCreatePage.tsx b/viewer/src/pages/FeedbackCreatePage.tsx
index 7104562..88b4acd 100644
--- a/viewer/src/pages/FeedbackCreatePage.tsx
+++ b/viewer/src/pages/FeedbackCreatePage.tsx
@@ -4,9 +4,9 @@ import { useSettingsStore } from "@/store/useSettingsStore";
import { useSyncChannelId } from "@/hooks/useSyncChannelId";
import { DynamicForm } from "@/components/DynamicForm";
import {
- getFeedbackSchema,
+ getFeedbackFields,
createFeedback,
- type FeedbackSchema,
+ type FeedbackField,
type CreateFeedbackRequest,
} from "@/services/feedback";
import { ErrorDisplay } from "@/components/ErrorDisplay";
@@ -17,7 +17,7 @@ export function FeedbackCreatePage() {
const navigate = useNavigate();
const { projectId, channelId } = useSettingsStore();
- const [schema, setSchema] = useState(null);
+ const [schema, setSchema] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [submitMessage, setSubmitMessage] = useState(null);
@@ -28,8 +28,13 @@ export function FeedbackCreatePage() {
const fetchSchema = async () => {
try {
setLoading(true);
- const schemaData = await getFeedbackSchema(projectId, channelId);
- setSchema(schemaData);
+ const schemaData = await getFeedbackFields(projectId, channelId);
+ // ID, Created, Updated, Issue 필드 제외
+ const filteredSchema = schemaData.filter(
+ (field) =>
+ !["id", "createdAt", "updatedAt", "issues"].includes(field.id),
+ );
+ setSchema(filteredSchema);
} catch (err) {
setError(
err instanceof Error ? err.message : "폼을 불러오는 데 실패했습니다.",
@@ -91,7 +96,7 @@ export function FeedbackCreatePage() {
{schema && (
diff --git a/viewer/src/pages/FeedbackDetailPage.tsx b/viewer/src/pages/FeedbackDetailPage.tsx
index 17c8cdb..3e00cf9 100644
--- a/viewer/src/pages/FeedbackDetailPage.tsx
+++ b/viewer/src/pages/FeedbackDetailPage.tsx
@@ -7,6 +7,12 @@ import {
updateFeedback,
} from "@/services/feedback";
import { ErrorDisplay } from "@/components/ErrorDisplay";
+import {
+ Card,
+ CardContent,
+ CardHeader,
+ CardTitle,
+} from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
export function FeedbackDetailPage() {
@@ -128,31 +134,35 @@ export function FeedbackDetailPage() {
-
-
-
- ID: {feedback?.id}
-
-
- 생성일:{" "}
- {feedback?.createdAt
- ? new Date(feedback.createdAt).toLocaleString("ko-KR")
- : "N/A"}
-
-
-
-
- {successMessage && (
-
- {successMessage}
+
+
+
+
피드백 정보
+
+ ID: {feedback?.id}
+
+ 생성일:{" "}
+ {feedback?.createdAt
+ ? new Date(feedback.createdAt).toLocaleString("ko-KR")
+ : "N/A"}
+
+
- )}
-
+
+
+
+ {successMessage && (
+
+ {successMessage}
+
+ )}
+
+
);
}
diff --git a/viewer/src/pages/FeedbackListPage.tsx b/viewer/src/pages/FeedbackListPage.tsx
index 78d19d8..b53239a 100644
--- a/viewer/src/pages/FeedbackListPage.tsx
+++ b/viewer/src/pages/FeedbackListPage.tsx
@@ -5,9 +5,9 @@ import { useSyncChannelId } from "@/hooks/useSyncChannelId";
import { DynamicTable } from "@/components/DynamicTable";
import {
getFeedbacks,
- getFeedbackSchema,
+ getFeedbackFields,
type Feedback,
- type FeedbackSchema,
+ type FeedbackField,
} from "@/services/feedback";
import { ErrorDisplay } from "@/components/ErrorDisplay";
import { Button } from "@/components/ui/button";
@@ -17,7 +17,7 @@ export function FeedbackListPage() {
const { projectId, channelId } = useSettingsStore();
const navigate = useNavigate();
- const [schema, setSchema] = useState(null);
+ const [schema, setSchema] = useState(null);
const [feedbacks, setFeedbacks] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
@@ -30,7 +30,7 @@ export function FeedbackListPage() {
setLoading(true);
setError(null);
- const schemaData = await getFeedbackSchema(projectId, channelId);
+ const schemaData = await getFeedbackFields(projectId, channelId);
setSchema(schemaData);
const feedbacksData = await getFeedbacks(projectId, channelId);
@@ -67,11 +67,13 @@ export function FeedbackListPage() {
{error && }
{schema && (
-
+
+
+
)}
);
diff --git a/viewer/src/services/feedback.ts b/viewer/src/services/feedback.ts
index e480b39..400676b 100644
--- a/viewer/src/services/feedback.ts
+++ b/viewer/src/services/feedback.ts
@@ -188,5 +188,11 @@ export const updateFeedback = async (
if (!response.ok) {
await handleApiError("피드백 수정에 실패했습니다.", response);
}
+
+ const contentLength = response.headers.get("Content-Length");
+ if (contentLength === "0" || !contentLength) {
+ return {} as Feedback; // 혹은 적절한 기본 객체
+ }
+
return response.json();
};
diff --git a/viewer/src/store/useSettingsStore.ts b/viewer/src/store/useSettingsStore.ts
index 81dc0db..b09bf16 100644
--- a/viewer/src/store/useSettingsStore.ts
+++ b/viewer/src/store/useSettingsStore.ts
@@ -1,11 +1,23 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";
-export const useSettingsStore = create()(
+
+interface SettingsState {
+ projectId: string;
+ channelId: string;
+ theme: "light" | "dark" | "system";
+ setProjectId: (projectId: string) => void;
+ setChannelId: (channelId: string) => void;
+ setTheme: (theme: "light" | "dark" | "system") => void;
+}
+
+export const useSettingsStore = create()(
persist(
(set) => ({
- projectId: "1", // 기본 프로젝트 ID를 1로 설정
+ projectId: "1", // 기본 프로젝트 ID
+ channelId: "4", // 기본 채널 ID
theme: "system",
setProjectId: (projectId) => set({ projectId }),
+ setChannelId: (channelId) => set({ channelId }),
setTheme: (theme) => set({ theme }),
}),
{
@@ -13,3 +25,4 @@ export const useSettingsStore = create()(
},
),
);
+
diff --git a/viewer/tsconfig.json b/viewer/tsconfig.json
index c955ba6..bf9832c 100644
--- a/viewer/tsconfig.json
+++ b/viewer/tsconfig.json
@@ -8,6 +8,7 @@
/* Bundler mode */
"moduleResolution": "bundler",
+ "allowJs": false,
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
@@ -25,5 +26,5 @@
"@/*": ["./src/*"]
}
},
- "include": ["src"]
+ "include": ["src", "effort_js/src/services/error.js", "effort_js/src/services/feedback.js", "effort_js/src/services/issue.js", "effort_js/src/services/project.js"]
}
diff --git a/viewer/vite.config.ts b/viewer/vite.config.ts
index 10a133b..8efd243 100644
--- a/viewer/vite.config.ts
+++ b/viewer/vite.config.ts
@@ -18,6 +18,7 @@ export default defineConfig(({ mode }) => {
alias: {
"@": path.resolve(__dirname, "./src"),
},
+ extensions: [".ts", ".tsx", ".mjs", ".mts", ".json"],
},
server: {
proxy: {