Skip to content

Commit a247a30

Browse files
committed
feat: 인터뷰 관련 API의 반환 타입 수정 및 오류 처리 개선, 로딩 컴포넌트 변경 및 reissue 엔드포인트 수정
1 parent c8c89d2 commit a247a30

30 files changed

+1614
-442
lines changed

apis/ai-interview.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export async function generateQuestions(
3838
interviewId: string,
3939
memberInterviewId: string,
4040
payload?: InterviewStartResponseDTO
41-
): Promise<InterviewSession | boolean> {
41+
): Promise<InterviewSession> {
4242
const updatedPayload = {
4343
...payload,
4444
result: {
@@ -54,7 +54,9 @@ export async function generateQuestions(
5454
`/interview/${interviewId}/${memberInterviewId}/generate_questions`,
5555
updatedPayload
5656
)
57-
if (typeof res === 'boolean') return res
57+
if (typeof res === 'boolean') {
58+
throw new Error('세션 생성에 실패했습니다.')
59+
}
5860
return toCamelCaseInterviewSession(res)
5961
}
6062

@@ -75,12 +77,14 @@ export async function generateFollowUpQuestions(
7577
sessionId: string,
7678
index: number,
7779
payload?: any
78-
): Promise<InterviewSession | boolean> {
80+
): Promise<InterviewSession> {
7981
const res = await aiFetch.post<any>(
8082
`/interview/session/${sessionId}/qa/${index}/generate_follow-ups`,
8183
payload
8284
)
83-
if (typeof res === 'boolean') return res
85+
if (typeof res === 'boolean') {
86+
throw new Error('후속 질문 생성에 실패했습니다.')
87+
}
8488
return toCamelCaseInterviewSession(res)
8589
}
8690

@@ -104,25 +108,29 @@ export async function generateFeedback(
104108
sessionId: string,
105109
index: number,
106110
payload?: any
107-
): Promise<InterviewSession | boolean> {
111+
): Promise<InterviewSession> {
108112
const res = await aiFetch.post<any>(
109113
`/interview/session/${sessionId}/qa/${index}/feedback`,
110114
payload
111115
)
112-
if (typeof res === 'boolean') return res
116+
if (typeof res === 'boolean') {
117+
throw new Error('피드백 생성에 실패했습니다.')
118+
}
113119
return toCamelCaseInterviewSession(res)
114120
}
115121

116122
// 6. 최종 리포트 생성
117123
export async function generateFinalReport(
118124
sessionId: string,
119125
payload?: any
120-
): Promise<InterviewSession | boolean> {
126+
): Promise<InterviewSession> {
121127
const res = await aiFetch.post<any>(
122128
`/interview/session/${sessionId}/report`,
123129
payload
124130
)
125-
if (typeof res === 'boolean') return res
131+
if (typeof res === 'boolean') {
132+
throw new Error('최종 리포트 생성에 실패했습니다.')
133+
}
126134
return toCamelCaseInterviewSession(res)
127135
}
128136

app/workspace/interviews/group/community/[id]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import type { GroupInterviewDetailDTO } from '@/apis/types/interview-types'
1919
import { useQuery } from '@tanstack/react-query'
2020
import { useMemberSession } from '@/components/member-session-context'
2121
import { use as usePromise } from 'react'
22-
import LoadingSpinner from '@/components/loading'
22+
import LoadingSpinner from '@/components/loading-full-screen'
2323

2424
export default function InterviewPostDetailPage({
2525
params,

app/workspace/interviews/group/community/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { HeaderWithNotifications } from '@/components/header-with-notifications'
1818
import { CommunityLayout } from '@/components/community-layout'
1919
import { getGroupInterviewCards } from '@/apis/interview'
2020
import { useQuery } from '@tanstack/react-query'
21-
import LoadingSpinner from '@/components/loading'
21+
import LoadingSpinner from '@/components/loading-full-screen'
2222

2323
export default function InterviewCommunityPage() {
2424
const { data, isLoading, error } = useQuery({

app/workspace/interviews/group/waiting/[id]/page.tsx

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,15 @@ import { Users, User, Brain } from 'lucide-react'
2222
import { formatCountdownString } from '@/utils/date/convertAllDate'
2323
import { Avatar, AvatarFallback } from '@/components/ui/avatar'
2424
import { CheckCircle } from 'lucide-react'
25-
import LoadingSpinner from '@/components/loading'
25+
import LoadingSpinner from '@/components/loading-full-screen'
26+
import { toast } from 'sonner'
27+
import {
28+
Dialog,
29+
DialogContent,
30+
DialogHeader,
31+
DialogTitle,
32+
DialogFooter,
33+
} from '@/components/ui/dialog'
2634

2735
export default function InterviewWaitingRoomPage({
2836
params,
@@ -44,6 +52,7 @@ export default function InterviewWaitingRoomPage({
4452
const timerRef = useRef<NodeJS.Timeout | null>(null)
4553
const router = useRouter()
4654
const [formattedStart, setFormattedStart] = useState('-')
55+
const [startDialogOpen, setStartDialogOpen] = useState(false)
4756

4857
const {
4958
data: interview,
@@ -123,7 +132,7 @@ export default function InterviewWaitingRoomPage({
123132

124133
const startInterview = useCallback(() => {
125134
if (participants?.length === 0) {
126-
alert('참가자가 없어요.')
135+
toast.error('참가자가 없어요.')
127136
router.replace('/workspace/interviews')
128137
return null
129138
}
@@ -137,17 +146,10 @@ export default function InterviewWaitingRoomPage({
137146

138147
const handleEarlyStart = () => {
139148
if (!isHost) {
140-
alert('면접 호스트만 면접을 시작할 수 있습니다.')
149+
toast.error('면접 호스트만 면접을 시작할 수 있습니다.')
141150
return
142151
}
143-
144-
if (
145-
confirm(
146-
'면접을 지금 시작하시겠습니까? 모든 참가자에게 알림이 전송됩니다.'
147-
)
148-
) {
149-
startInterview()
150-
}
152+
setStartDialogOpen(true)
151153
}
152154

153155
if (isLoading) {
@@ -159,7 +161,7 @@ export default function InterviewWaitingRoomPage({
159161
}
160162

161163
if (isError) {
162-
alert('면접 정보를 불러오는 중 오류가 발생했어요.')
164+
toast.error('면접 정보를 불러오는 중 오류가 발생했어요.')
163165
router.replace('/workspace/interviews')
164166
return null
165167
}
@@ -343,6 +345,31 @@ export default function InterviewWaitingRoomPage({
343345
</CardContent>
344346
</Card>
345347
</div>
348+
<Dialog open={startDialogOpen} onOpenChange={setStartDialogOpen}>
349+
<DialogContent>
350+
<DialogHeader>
351+
<DialogTitle>면접 시작</DialogTitle>
352+
</DialogHeader>
353+
<div>
354+
면접을 지금 시작하시겠습니까? <br />
355+
모든 참가자에게 알림이 전송됩니다.
356+
</div>
357+
<DialogFooter>
358+
<Button variant="outline" onClick={() => setStartDialogOpen(false)}>
359+
취소
360+
</Button>
361+
<Button
362+
className="bg-[#8FD694] hover:bg-[#7ac47f] text-white"
363+
onClick={() => {
364+
setStartDialogOpen(false)
365+
startInterview()
366+
}}
367+
>
368+
확인
369+
</Button>
370+
</DialogFooter>
371+
</DialogContent>
372+
</Dialog>
346373
</div>
347374
)
348375
}

app/workspace/interviews/individual/waiting/[id]/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { useQuery } from '@tanstack/react-query'
1616
import { getGroupInterviewDetail } from '@/apis/interview'
1717
import { useRouter } from 'next/navigation'
1818
import { formatCountdownString } from '@/utils/date/convertAllDate'
19-
import LoadingSpinner from '@/components/loading'
19+
import LoadingSpinner from '@/components/loading-full-screen'
2020
import { toast } from 'sonner'
2121

2222
export default function IndividualInterviewWaitingRoomPage({

app/workspace/interviews/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { useQuery } from '@tanstack/react-query'
1313
import { useMemberSession } from '@/components/member-session-context'
1414
import { useRouter } from 'next/navigation'
1515
import type { InterviewCardDTO } from '@/apis/types/interview-types'
16-
import LoadingSpinner from '@/components/loading'
16+
import LoadingSpinner from '@/components/loading-full-screen'
1717
import { toast } from 'sonner'
1818
import DeleteDialog from '../profile/components/DeleteDialog'
1919
import { PREPARE_FOR_RELEASE } from '@/constant'

0 commit comments

Comments
 (0)