Skip to content

✨Feat: 메인 홈 반려동물 선택형 건강 레포트 UI 및 데이터 연동 - #61

Merged
sooloin merged 4 commits into
DoDo-Project:developfrom
sooloin:feature/60
Jun 15, 2026
Merged

✨Feat: 메인 홈 반려동물 선택형 건강 레포트 UI 및 데이터 연동#61
sooloin merged 4 commits into
DoDo-Project:developfrom
sooloin:feature/60

Conversation

@sooloin

@sooloin sooloin commented Jun 15, 2026

Copy link
Copy Markdown
Collaborator

📄 작업 내용 (Description)

이번 PR에서 변경되거나 추가된 주요 작업을 간단히 설명해주세요.

메인 홈 상단 영역을 메인 정보 조회 API 기반으로 연결
반려동물 등록 여부에 따라 홈 UI가 분기되도록 구현

  • 반려동물 미등록 시 기존 홈 메인 UI 유지
  • 반려동물 등록 시 선택형 프로필 카드 + 건강 레포트 UI 노출
  • 선택된 반려동물 기준 최신 건강 레포트 노출
  • healthReportContent JSON 파싱 후 recommendations 우선 노출
  • 백엔드 응답 변경 대응
    • title / summary / content 순서로 레포트 노출
    • summary 중복 노출되지 않도록 수정
  • 우측 프로필 카드 정보 구조 정리
    • 이름, 나이, 품종, 체중만 노출
    • 불필요한 PROFILE/종 구분 텍스트 제거
  • 하단 반려동물 썸네일 크기 및 정렬 보정

🔗 관련 이슈 (Related Issues)

작업한 이슈 번호를 아래 형식으로 PULL REQUEST BODY에 작성해주세요.
(PR 머지 시 해당 이슈가 자동으로 종료됩니다.)


✅ 체크리스트 (Checklist)

PR을 보내기 전 아래 항목들을 모두 확인해주세요.

  • PR 제목은 커밋 컨벤션을 따랐습니다.
  • 관련 이슈를 연결했습니다.
  • 스스로 코드를 검토하고 불필요한 코드를 제거했습니다.
  • 코드 스타일이 프로젝트 규칙과 일치합니다. (Style)
  • 새로운 기능에 대한 테스트 코드를 추가했거나, 기존 테스트가 모두 통과했습니다. (Test)

📸 스크린샷 (Screenshots)

작업 내용과 관련된 스크린샷이 있다면 첨부해주세요. (UI 변경이 있는 경우)

image

💬 기타 사항 (Etc)

리뷰어에게 전달하고 싶은 추가 정보가 있다면 자유롭게 작성해주세요.

sooloin added 3 commits June 15, 2026 09:15
- 메인페이지 정보 조회 API 타입 및 react-query 훅 추가
- 선택된 반려동물 기준 최신 AI 건강 레포트 노출 로직 구현
- 공지사항/바로가기 섹션을 데이터 기반 UI로 재구성
- 반려동물 없음, 레포트 없음, 로딩, 에러 상태 UI 추가

`DoDo-Project#60`
- 메인 홈 API 연동 및 반려동물 선택 상태 추가
- 반려동물 미등록 시 기존 홈 UI 유지
- 반려동물 등록 시 선택형 프로필 카드와 건강 레포트 UI 노출
- healthReportContent JSON 파싱 후 recommendations 우선 노출
- 레포트 영역에 title, summary, content 순서 적용
- 우측 프로필 카드 정보 구조 및 썸네일 크기/정렬 개선

`DoDo-Project#60`
@sooloin
sooloin requested review from WhiteBin-bin and limhb708 June 15, 2026 04:12
@sooloin sooloin self-assigned this Jun 15, 2026
@sooloin sooloin added ✨ Feature 새 기능 혹은 요구 사항 😸 조수빈 조수빈 파트 labels Jun 15, 2026
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

@sooloin is attempting to deploy a commit to the sooloin's projects Team on Vercel.

A member of the Team first needs to authorize it.

@sooloin sooloin changed the title Feature/60 메인 홈 반려동물 선택형 건강 레포트 UI 및 데이터 연동 Jun 15, 2026
@vercel

vercel Bot commented Jun 15, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
dodo-frontend Ready Ready Preview, Comment Jun 15, 2026 4:26am

@sooloin sooloin changed the title 메인 홈 반려동물 선택형 건강 레포트 UI 및 데이터 연동 ✨Feat: 메인 홈 반려동물 선택형 건강 레포트 UI 및 데이터 연동 Jun 15, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements the main dashboard features for logged-in users, including fetching pet profiles and AI health reports, handling loading/error states, and displaying interactive pet selection and report summaries. The review feedback highlights several improvement opportunities: preventing UI flickering during background refetches by using isLoading instead of isFetching, optimizing the getLatestReportByPet function to avoid unnecessary array sorting and date object creation, safely handling potential non-object values returned by JSON.parse in extractHealthReportRecommendations, and ensuring raw JSON is not rendered to the user when recommendations are empty.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread src/pages/main/ui/LoggedInHome.tsx Outdated
Comment on lines +30 to +31
<HealthReportSection
isLoading={isLoading || isFetching}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

배경에서 데이터를 새로고침할 때(background refetch) isFetchingtrue가 되는데, 이로 인해 이미 화면에 표시되고 있던 데이터가 사라지고 스켈레톤 UI가 다시 노출되는 깜빡임 현상(UX 저하)이 발생할 수 있습니다.

React Query의 캐싱 이점을 살려 이미 데이터가 있을 때는 기존 데이터를 계속 보여주고, 최초 로딩 시에만 스켈레톤을 보여주도록 isLoading만 사용하는 것이 좋습니다.

Suggested change
<HealthReportSection
isLoading={isLoading || isFetching}
<HealthReportSection
isLoading={isLoading}

Comment thread src/pages/main/model/formatters.ts Outdated
Comment on lines +35 to +39
export function getLatestReportByPet<T extends { petId: number; checkupDate: string }>(petId: number, reports: T[]) {
return [...reports]
.filter((report) => report.petId === petId)
.sort((left, right) => new Date(right.checkupDate).getTime() - new Date(left.checkupDate).getTime())[0];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

getLatestReportByPet 함수는 매 렌더링마다 전체 리포트 배열을 복사하고 필터링한 뒤, 정렬 과정에서 new Date() 객체를 반복적으로 생성하여 성능 저하를 유발할 수 있습니다.

배열을 정렬하는 대신 단일 루프($O(N)$)를 돌며 가장 최신 리포트를 찾는 방식으로 최적화하면 불필요한 객체 생성과 정렬 비용을 크게 줄일 수 있습니다.

Suggested change
export function getLatestReportByPet<T extends { petId: number; checkupDate: string }>(petId: number, reports: T[]) {
return [...reports]
.filter((report) => report.petId === petId)
.sort((left, right) => new Date(right.checkupDate).getTime() - new Date(left.checkupDate).getTime())[0];
}
export function getLatestReportByPet<T extends { petId: number; checkupDate: string }>(petId: number, reports: T[]): T | undefined {
let latest: T | undefined = undefined;
let latestTime = -1;
for (const report of reports) {
if (report.petId === petId) {
const time = new Date(report.checkupDate).getTime();
if (!Number.isNaN(time) && time > latestTime) {
latestTime = time;
latest = report;
}
}
}
return latest;
}

Comment thread src/pages/main/model/formatters.ts Outdated
Comment on lines +59 to +62
const parsed = JSON.parse(content) as ParsedHealthReportContent;
if (!Array.isArray(parsed.recommendations)) {
return [];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

JSON.parse(content)의 결과가 null이거나 객체가 아닌 경우(예: "null", "123" 등), parsed.recommendations에 접근할 때 TypeError가 발생하여 catch 블록으로 빠지게 됩니다. 예외 발생에 의존하기보다 안전하게 타입 및 null 체크를 수행하는 것이 좋습니다.

Suggested change
const parsed = JSON.parse(content) as ParsedHealthReportContent;
if (!Array.isArray(parsed.recommendations)) {
return [];
}
const parsed = JSON.parse(content) as ParsedHealthReportContent | null;
if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.recommendations)) {
return [];
}

Comment on lines +161 to +162
const reportPrimaryContent =
reportRecommendations[0] || (selectedReport ? summarizeContent(selectedReport.healthReportContent, 96) : '');

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

만약 selectedReport.healthReportContent가 JSON 문자열이고 recommendations가 비어있는 경우, reportPrimaryContent는 raw JSON 문자열 전체를 summarizeContent하여 화면에 그대로 노출하게 됩니다. 이는 사용자에게 깨진 JSON 텍스트를 보여주는 UX 문제를 야기할 수 있습니다.

healthReportContent가 JSON 형식일 때의 안전한 폴백 메시지를 정의하거나, JSON 내부의 다른 텍스트 필드(예: content 등)를 파싱하여 노출하도록 개선하는 것이 좋습니다.

- 배경 refetch 시 스켈레톤 깜빡임이 발생하지 않도록 isLoading만 사용
- 최신 건강 레포트 탐색 로직을 단일 순회 방식으로 최적화
- healthReportContent JSON 파싱 시 null 및 타입 안전성 체크 추가
- recommendation 부재 시 raw JSON이 노출되지 않도록 안전한 본문 fallback 처리

`DoDo-Project#60`
@sooloin
sooloin merged commit 3f63230 into DoDo-Project:develop Jun 15, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 새 기능 혹은 요구 사항 😸 조수빈 조수빈 파트

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 메인페이지 반려동물 선택 기반 AI 건강 레포트 Preview 기능 구현

2 participants