Skip to content

[feat] AI 요약 플로우 UI 구현 (로딩 오버레이 + 스켈레톤 + 토스트) #84

@mgYang53

Description

@mgYang53

📄 설명

약속 회고 생성 페이지에서 AI 요약 시작하기 버튼 클릭 시 약속 회고 결과 페이지로 이동하여 로딩 상태를 표시하고, 완료 시 토스트 알림을 보여주는 플로우를 구현합니다.

플로우

MeetingRetrospectiveCreatePage → [AI 요약 시작하기 클릭]
  → navigate → MeetingRetrospectivePage (state: { fromAiSummary: true })
    → 딤 오버레이 + Spinner + "AI가 사전 의견을 요약 중이에요" 메시지
    → 페이지 뒤에는 스켈레톤 콘텐츠 표시
    → 생성 완료 시: 오버레이 닫힘 → 토스트 "AI 요약이 완료되었습니다" (화면 중앙, 딤 없음, 3초 후 자동 사라짐)

참고: 약속 회고 요약 요청 API(POST)는 백엔드 확인 필요. 현재는 API 호출 없이 setTimeout mock으로 구현하고, API 확정 후 교체 예정.

API 관련 (백엔드 확인 필요)

  • GET /api/meetings/{meetingId}/retrospectives/summary — AI 요약 조회 (openapi.yaml에 존재)
  • PATCH /api/meetings/{meetingId}/retrospectives/summary — AI 요약 수정 (openapi.yaml에 존재)
  • AI 요약 생성 트리거 POST 엔드포인트 — openapi.yaml에 없음, 백엔드에 확인 필요

✅ 해야 할 일

공통 UI 컴포넌트

  • src/shared/ui/Toast.tsx 생성 — 화면 중앙 토스트 알림 (딤 없음, 자동 dismiss, createPortal)
  • src/shared/ui/AiLoadingOverlay.tsx 생성 — 딤 오버레이 + Spinner + 메시지 (createPortal)
  • src/shared/ui/index.ts에 Toast, AiLoadingOverlay export 추가

Feature 컴포넌트

  • src/features/retrospectives/components/RetrospectiveSummarySkeleton.tsx 생성 — 요약 결과 스켈레톤
  • src/features/retrospectives/components/index.ts에 export 추가

페이지 수정

  • MeetingRetrospectiveCreatePage.tsx — "AI 요약 시작하기" 버튼에 onClick 핸들러 추가 (navigate with state)
  • MeetingRetrospectivePage.tsx — 로딩 오버레이 + 스켈레톤 + 토스트 통합 구현
    • location.state.fromAiSummary 감지
    • 오버레이 → 토스트 전환 로직
    • 새로고침 시 오버레이 재표시 방지 (window.history.replaceState)

API 연동 (후속 작업 — 백엔드 API 확정 후)

  • src/features/retrospectives/retrospectives.endpoints.ts 생성
  • src/features/retrospectives/retrospectives.types.ts 생성
  • src/features/retrospectives/retrospectives.api.ts 생성
  • src/features/retrospectives/hooks/retrospectiveQueryKeys.ts 생성
  • src/features/retrospectives/hooks/useRetrospectiveSummary.ts 생성
  • MeetingRetrospectivePage에서 setTimeout mock → 실제 API 호출 교체

검증

  • pnpm build 타입 에러 없이 성공
  • pnpm lint 에러 없음
  • 수동 테스트: 생성 페이지 → AI 요약 시작 → 결과 페이지 이동 → 오버레이 → 토스트 → 자동 dismiss

📝 메모

참조 파일

  • src/shared/ui/Modal.tsx — 딤 오버레이 스타일 (bg-black/60), portal 패턴
  • src/shared/ui/Spinner.tsx — 로딩 스피너 (재사용)
  • src/features/topics/components/TopicListSkeleton.tsx — 스켈레톤 패턴 (bg-grey-200 rounded animate-pulse)
  • src/store/globalModalStore.ts — 참조만 (커스텀 오버레이 사용, globalModalStore는 alert/error/confirm 전용)

설계 결정

  • Toast: 프로젝트에 토스트 라이브러리 없으므로 커스텀 구현 (createPortal + setTimeout)
  • AiLoadingOverlay: globalModalStore 대신 독립 컴포넌트 (버튼 없는 순수 로딩 상태)
  • 네비게이션 state: location.state.fromAiSummary로 전달 (URL에 노출되지 않음, 새로고침 시 자연스럽게 리셋)

Metadata

Metadata

Assignees

Labels

feat새로운 기능 추가

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions