중간 수정. 피드백 디테일보기 해결

This commit is contained in:
Lectom C Han
2025-08-03 18:30:02 +09:00
parent 26fbb3f4c0
commit 32506d22bb
4 changed files with 29 additions and 7 deletions

View File

@@ -1,4 +1,10 @@
# Q&A 뷰어 프로젝트
## 0. 프젝트 전체 작업 진행 원칙
- GEMINI cli로 하는 모든 작업에 대해 한글로 응답하며, 기능단위 결과를 TODO.md 에 남긴다.
- 결과의 기록은 date 명령을 이용해 KST 기준으로 시분초까지 작성한다.
- node_modules를 제외한 이 프로젝트에서 생성하는 파일은 ts 혹은 tsx 이며 js 생성시
- 기능 단위 완성 후 사용자 승인을 받고 Biome를 이용해 lint 및 format 검사를 수행한다.
- 최종적으로 사용자에게 git commit을 한 뒤 TODO.md에 기록한다.
## 1. 프로젝트 개요
@@ -13,7 +19,7 @@
- OIDC 표준을 이용한 사용자 인증
## 3. 기술 스택
- **Language**: `typescript`
- **Package Manager**: `pnpm`
- **Framework**: `React`
- **Build Tool**: `Vite`
@@ -47,7 +53,6 @@
- **진행할 작업**:
- **테마 커스터마이징**: Dracula 테마를 다크 모드에 적용하고, 기본 테마를 라이트 모드로 설정
- **동적 폼 개선**: Zod와 같은 라이브러리를 활용하여 스키마 기반의 동적 데이터 유효성 검사 구현
- **코드 품질 관리**: Biome을 프로젝트에 통합하여 코드 포맷팅과 린트 검사를 자동화하고, 일관된 코드 스타일 유지
### Phase 3: 인증 및 배포 (예정)

View File

@@ -20,7 +20,6 @@
- [x] Light/Dark/System 테마 기능 구현 및 커스텀 테마 적용 (완료: 2025-07-31 17:20:41)
- [x] TypeScript 및 빌드 오류 디버깅 및 해결 (완료: 2025-07-31 17:20:41)
- [ ] 동적 폼에 데이터 유효성 검사 기능 추가
- [ ] Biome을 이용한 코드 포맷팅 및 린트 규칙 적용 및 검사
## Phase 3: 인증 및 배포

View File

@@ -19,6 +19,8 @@ interface DynamicFormProps {
onSubmit: (formData: Record<string, unknown>) => Promise<void>;
initialData?: Record<string, unknown>;
submitButtonText?: string;
onCancel?: () => void;
cancelButtonText?: string;
}
export function DynamicForm({
@@ -26,6 +28,8 @@ export function DynamicForm({
onSubmit,
initialData = EMPTY_INITIAL_DATA, // 기본값으로 상수 사용
submitButtonText = "제출",
onCancel,
cancelButtonText = "취소",
}: DynamicFormProps) {
const [formData, setFormData] =
useState<Record<string, unknown>>(initialData);
@@ -107,9 +111,16 @@ export function DynamicForm({
{renderField(field)}
</div>
))}
<Button type="submit" disabled={isSubmitting}>
{isSubmitting ? "전송 중..." : submitButtonText}
</Button>
<div className="flex justify-between">
<Button type="submit" disabled={isSubmitting}>
{isSubmitting ? "전송 중..." : submitButtonText}
</Button>
{onCancel && (
<Button type="button" variant="outline" onClick={onCancel}>
{cancelButtonText}
</Button>
)}
</div>
</form>
);
}

View File

@@ -2,7 +2,11 @@ import { useState, useEffect, useMemo } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { DynamicForm } from "@/components/DynamicForm";
import { useSyncChannelId } from "@/hooks/useSyncChannelId";
import { getFeedbackById, updateFeedback } from "@/services/feedback";
import {
getFeedbackById,
updateFeedback,
getFeedbackFields,
} from "@/services/feedback";
import { ErrorDisplay } from "@/components/ErrorDisplay";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Separator } from "@/components/ui/separator";
@@ -147,6 +151,9 @@ export function FeedbackDetailPage() {
initialData={initialData}
onSubmit={handleSubmit}
submitButtonText="수정하기"
onCancel={() =>
navigate(`/projects/${projectId}/channels/${channelId}/feedbacks`)
}
/>
{successMessage && (
<div className="mt-4 p-3 bg-green-100 text-green-800 rounded-md">