Skip to content

Commit 0799abc

Browse files
committed
fix: 리포트 페이지 버튼 기능 연결 및 conversationScript ref로 변경
- 리포트 페이지 버튼 기능 연결 (공유하기, 다시하기, 홈으로 돌아가기) - conversationScript state를 useRef로 변경하여 불필요한 리렌더링 방지 - 질문 인덱스 리셋 시 conversationScript ref 초기화 - import 순서 정리
1 parent 4958da6 commit 0799abc

2 files changed

Lines changed: 86 additions & 8 deletions

File tree

app/(default)/practice/[situationId]/[detailId]/dial/call/page.tsx

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,19 @@ export default function CallPage() {
4343
const [currentQuestionIndex, setCurrentQuestionIndex] = useState(0);
4444
const [isSubmitting, setIsSubmitting] = useState(false);
4545
const [hasProcessedAnswer, setHasProcessedAnswer] = useState(false);
46+
const conversationScriptRef = useRef<ConversationScript[]>([]);
4647
const params = useParams();
4748
const router = useRouter();
4849
const detailId = (params.detailId as string) || "";
4950
const situationId = params.situationId as string;
5051

52+
// 질문 인덱스가 0으로 리셋될 때 대화 스크립트도 초기화
53+
useEffect(() => {
54+
if (currentQuestionIndex === 0) {
55+
conversationScriptRef.current = [];
56+
}
57+
}, [currentQuestionIndex]);
58+
5159
// detailId가 없으면 기본값 설정 (랜덤 연습 등에서 직접 접근한 경우)
5260
useEffect(() => {
5361
if (!detailId && situationId) {
@@ -157,18 +165,19 @@ export default function CallPage() {
157165

158166
setHasProcessedAnswer(true);
159167

168+
// 대화 스크립트에 추가
169+
conversationScriptRef.current = [
170+
...conversationScriptRef.current,
171+
newScript,
172+
];
173+
160174
// 다음 질문으로 이동 또는 완료
161175
if (currentQuestionIndex < QUESTIONS.length - 1) {
162176
const nextIndex = currentQuestionIndex + 1;
163-
setConversationScript((prev) => [...prev, newScript]);
164177
setCurrentQuestionIndex(nextIndex);
165178
} else {
166179
// 5번 질문 완료 - API 호출
167-
setConversationScript((prev) => {
168-
const updatedScript = [...prev, newScript];
169-
handleSubmitConversation(updatedScript);
170-
return updatedScript;
171-
});
180+
handleSubmitConversation(conversationScriptRef.current);
172181
}
173182
resetTranscript();
174183
}, [

app/(report)/report/[reportId]/components/ReportContent.tsx

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
"use client";
22

33
import { Button } from "@team-numberone/daepiro-design-system";
4+
import { useRouter } from "next/navigation";
5+
import {
6+
detailSituations,
7+
type SituationId,
8+
} from "@/app/(default)/constants/detailSituations";
49
import { IconWrapper } from "@/components/icons/IconWrapper";
510
import { useReport } from "../hooks/useReport";
611
import {
@@ -15,9 +20,69 @@ interface ReportContentProps {
1520

1621
export function ReportContent({ reportId }: ReportContentProps) {
1722
const { data: result } = useReport(reportId);
23+
const router = useRouter();
1824

1925
const imagePath = getReportImagePaths(result.title);
2026

27+
// 결과지 공유하기
28+
const handleShare = async () => {
29+
const shareData = {
30+
title: `${result.title} - ${result.totalScore}점`,
31+
text: `119 신고 연습 결과: ${result.title}\n총점: ${result.totalScore}점\n${result.comment}`,
32+
url: window.location.href,
33+
};
34+
35+
if (navigator.share) {
36+
try {
37+
await navigator.share(shareData);
38+
} catch (error) {
39+
// 사용자가 공유를 취소한 경우 무시
40+
if ((error as Error).name !== "AbortError") {
41+
console.error("공유 실패:", error);
42+
}
43+
}
44+
} else {
45+
// Web Share API를 지원하지 않는 경우 클립보드에 복사
46+
try {
47+
await navigator.clipboard.writeText(window.location.href);
48+
alert("링크가 클립보드에 복사되었습니다.");
49+
} catch (error) {
50+
console.error("클립보드 복사 실패:", error);
51+
alert("공유 기능을 사용할 수 없습니다.");
52+
}
53+
}
54+
};
55+
56+
// 다시하기 (랜덤 연습)
57+
const handleRetry = () => {
58+
// 모든 상세상황을 평탄화하여 배열로 만들기
59+
const allDetailSituations: Array<{
60+
situationId: SituationId;
61+
detailId: string;
62+
}> = [];
63+
64+
(Object.keys(detailSituations) as SituationId[]).forEach((situationId) => {
65+
detailSituations[situationId].forEach((detail) => {
66+
allDetailSituations.push({
67+
situationId,
68+
detailId: detail.id,
69+
});
70+
});
71+
});
72+
73+
// 랜덤으로 하나 선택
74+
const randomIndex = Math.floor(Math.random() * allDetailSituations.length);
75+
const selected = allDetailSituations[randomIndex];
76+
77+
// 다이얼 페이지로 이동
78+
router.push(`/practice/${selected.situationId}/${selected.detailId}/dial`);
79+
};
80+
81+
// 홈으로 돌아가기
82+
const handleGoHome = () => {
83+
router.push("/");
84+
};
85+
2186
return (
2287
<div className="px-5">
2388
{/* 제목 */}
@@ -102,7 +167,7 @@ export function ReportContent({ reportId }: ReportContentProps) {
102167
{/* 버튼들 */}
103168
<div className="flex flex-col gap-3 mt-auto pb-6">
104169
<div className="flex gap-3">
105-
<Button className="bg-[#EEEEF3]">
170+
<Button className="bg-[#EEEEF3]" onClick={handleShare}>
106171
<div className="text-body-1 font-bold text-gray-600 w-[130px]">
107172
결과지 공유하기
108173
</div>
@@ -111,11 +176,15 @@ export function ReportContent({ reportId }: ReportContentProps) {
111176
<Button
112177
className="border-2 border-solid border-[#EEEEF3] bg-white"
113178
full
179+
onClick={handleRetry}
114180
>
115181
<div className="text-body-1 font-bold text-gray-500">다시하기</div>
116182
</Button>
117183
</div>
118-
<Button className="w-full bg-green-500 text-white font-bold">
184+
<Button
185+
className="w-full bg-green-500 text-white font-bold"
186+
onClick={handleGoHome}
187+
>
119188
홈으로 돌아가기
120189
</Button>
121190
</div>

0 commit comments

Comments
 (0)