Skip to content

[FE] 대시보드 지표 카드 UI 추가 및 SSE 연결, 각 지표들의 실시간 데이터 업데이트 기능 추가#334

Merged
lee0jae330 merged 135 commits intodevelopfrom
feature/#302-fe-dashboard-card-ui
Feb 20, 2026
Merged

[FE] 대시보드 지표 카드 UI 추가 및 SSE 연결, 각 지표들의 실시간 데이터 업데이트 기능 추가#334
lee0jae330 merged 135 commits intodevelopfrom
feature/#302-fe-dashboard-card-ui

Conversation

@lee0jae330
Copy link
Collaborator

@lee0jae330 lee0jae330 commented Feb 19, 2026

#️⃣ 변경 사항

  • 대시보드 메인에서 실제 지표 카드 컴포넌트를 렌더링하도록 구조를 전환했습니다.
  • 대시보드 SSE 연결을 추가하고, 지표별 실시간 데이터 갱신 로직을 연동했습니다.
  • 대시보드 탭/카드 목록 조회 및 탭 편집(추가/수정/삭제) API 연동을 반영했습니다.
  • 메뉴/매출 지표 카드 DTO 및 타입을 서버 응답 구조에 맞게 정리했습니다.
  • 로딩/에러 처리(FetchBoundary, Suspense Skeleton)와 빈 상태 UI를 보강했습니다.

#️⃣ 작업 상세 내용

  • 상세 내용 1
    • DashboardMain/DashboardMainContent에서 카드 코드별 전용 컴포넌트(DashboardCard)를 렌더링하도록 변경
    • 매출/메뉴 지표 카드(실매출, 주문건수, 건당평균가, 매출추이, 피크타임, 요일별 매출, 메뉴 랭킹, 식재료 소진량, 시간대별 주문, 인기 메뉴 조합) API 조회 연결
    • 카드별 FetchBoundary 적용으로 카드 단위 로딩/에러 격리
  • 상세 내용 2
    • useDashboardSseConnection 추가: /api/sse/connection 수신 이벤트를 카드별 query cache에 반영
    • useDashboardCardSubscription 추가: 현재 대시보드의 카드 코드(topic) 구독/해지 API 호출
    • SSE 클라이언트 재시도/백오프 및 탭 전환 시 race condition 대응
    • 탭 상태를 인덱스 기반에서 dashboardId 기반으로 전환하고 탭 목록 API와 동기화

PR 포인트

#️⃣ 관련 이슈

📸 스크린샷 (선택)

변경 전

  • 대시보드 메인 카드가 mock/placeholder 위주로 표시되고 실시간 갱신이 없음

변경 후

  • 대시보드 지표 카드가 API 데이터로 렌더링됨
  • SSE 이벤트 수신 시 카드 데이터가 실시간으로 갱신됨
  • 탭 전환 시 해당 대시보드 카드 구독 토픽이 갱신됨
2026-02-19.8.51.47.mov
2026-02-19.8.52.18.mov
2026-02-19.8.52.56.mov
2026-02-19.8.53.44.mov

Empty View 추가

스크린샷 2026-02-20 오후 12 58 14 스크린샷 2026-02-20 오후 12 59 35 스크린샷 2026-02-20 오후 12 59 23 스크린샷 2026-02-20 오후 12 59 13 스크린샷 2026-02-20 오후 12 58 52 스크린샷 2026-02-20 오후 12 58 42 스크린샷 2026-02-20 오후 12 58 33

📎 참고할만한 자료 (선택)

  • SSE client: frontend/src/services/shared/sseClient.ts
  • SSE 연결/캐시 업데이트: frontend/src/hooks/dashboard/useDashboardSseConnection.ts
  • 카드 구독 훅: frontend/src/hooks/dashboard/useDashboardCardSubscription.ts
  • 대시보드 메인 렌더링: frontend/src/components/dashboard/dashboard-main/DashboardMain.tsx

mskwon02 and others added 30 commits February 13, 2026 10:04
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

이 PR은 대시보드 페이지에 실제 지표 카드를 추가하고 SSE(Server-Sent Events)를 통한 실시간 데이터 업데이트 기능을 구현한 대규모 작업입니다. 주요 변경 사항으로는 대시보드 카드별 전용 컴포넌트 렌더링, SSE 연결 및 구독 관리, API 연동, DTO/타입 리팩토링, 로딩/에러 처리 개선이 포함되어 있습니다.

Changes:

  • 대시보드 메인에서 카드 코드별 전용 컴포넌트를 렌더링하도록 구조 변경 (매출/메뉴 분석 지표 카드 추가)
  • SSE 클라이언트를 통한 실시간 데이터 갱신 기능 구현 (연결, 구독/해지, 캐시 업데이트)
  • 매출 유형/주문수단/결제수단 관련 DTO 및 타입을 서버 응답 구조에 맞게 리팩토링 (OrderMethod → OrderChannel)
  • FetchBoundary 및 빈 상태 UI 추가, 요일 인덱싱 로직 수정 등 여러 개선 사항 반영

Reviewed changes

Copilot reviewed 97 out of 101 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
frontend/src/hooks/dashboard/useDashboardSseConnection.ts SSE 연결 관리 및 카드별 실시간 데이터 업데이트 로직
frontend/src/hooks/dashboard/useDashboardCardSubscription.ts 대시보드 카드 구독/해지 관리 훅
frontend/src/hooks/dashboard/useDashboardCardList.ts 대시보드 카드 목록 조회 훅
frontend/src/hooks/dashboard/useDashboardCardDetailQueryOption.ts 카드 상세 쿼리 옵션 생성 훅
frontend/src/components/dashboard/dashboard-main/DashboardCard.tsx 카드 코드별 컴포넌트 매핑 및 렌더링
frontend/src/components/dashboard/dashboard-main/DashboardMain.tsx 대시보드 메인 로직 단순화 및 구독 훅 적용
frontend/src/components/dashboard/dashboard-main/DashboardMainContent.tsx 카드 렌더링 구조를 FetchBoundary 및 DefaultCardWrapper로 변경
frontend/src/components/dashboard/dashboard-sales/* 매출 관련 지표 카드 컴포넌트 (9개 파일)
frontend/src/components/dashboard/dashboard-menu/* 메뉴 관련 지표 카드 컴포넌트 (4개 파일)
frontend/src/components/sales/dashboard-sales-income/OrderChannelContent.tsx OrderMethod에서 OrderChannel로 이름 변경
frontend/src/components/sales/dashboard-sales-income/SalesTypeContent.tsx 매출 유형별 데이터 매핑 로직 업데이트
frontend/src/components/sales/dashboard-sales-income/PaymentMethodContent.tsx 결제수단별 데이터 매핑 로직 업데이트
frontend/src/components/sales/dashboard-sales-pattern/PeakTimeContent.tsx null 처리 로직 추가 및 요일 인덱싱 수정
frontend/src/components/sales/dashboard-sales-pattern/SalesByDayContent.tsx null 처리 및 showYGuideLine 제거
frontend/src/components/sales/dashboard-sales-trend/SalesTrendContent.tsx 차트 레이아웃 구조 변경
frontend/src/components/menu/dashboard-menu-order/TimeSlotMenuOrderCountCardContent.tsx 빈 상태 처리 추가
frontend/src/components/menu/dashboard-menu-combination/PopularMenuCombinationCardContent.tsx 빈 상태 처리 추가
frontend/src/components/shared/pagination/* pagenation에서 pagination으로 폴더명 수정
frontend/src/components/shared/line-chart/LineChart.tsx 라인 시리즈 렌더링 순서 변경
frontend/src/services/shared/sseClient.ts AbortController 중복 abort 방지 로직 추가
frontend/src/services/dashboard/* 대시보드 SSE 구독 API 및 분석 상세 API 추가
frontend/src/services/analysis/get.ts 분석 상세 조회 서비스 추가
frontend/src/types/sales/dto/* 매출 관련 DTO 타입 리팩토링 (RealTimeSales → RealSales, OrderMethod → OrderChannel)
frontend/src/types/sales/dashboard-sales-income/salesIncomeStructureInsight.ts 제네릭 타입으로 리팩토링
frontend/src/types/menu/dto/getPopularMenuCombinationDto.ts nullable 필드 추가 및 오타 수정
frontend/src/types/dashboard/dto/* SSE 구독 요청 DTO 추가
frontend/src/constants/sales/salesSource.ts TAKEOUT → TAKE_OUT, MOBILE → EASY_PAY 이름 변경
frontend/src/constants/sales/dashboard-sales-income/* OrderMethod에서 OrderChannel로 변경 및 예시 데이터 타입 개선
frontend/src/constants/dashboard/dashboardMetric.ts 카드 코드별 타입 가드 함수 추가
frontend/src/utils/sales/* 요일 인덱싱 수정 및 타입 변경 반영
frontend/src/utils/shared/bar-chart/getBarHeight.ts 주석을 한국어로 변경
frontend/src/mocks/auth/authHandler.ts passthrough 추가 (테스트 용도)
frontend/src/mocks/analysis/analysisHandler.ts 분석 API 모킹 핸들러 추가
Comments suppressed due to low confidence (2)

frontend/src/components/sales/dashboard-sales-income/OrderChannelContent.tsx:48

  • 타입 캐스팅이 필요한 이유를 확인해주세요. SalesIncomeStructureInsight<Extract<keyof typeof SALES_SOURCE, 'ORDER_METHOD'>>로 정의된 타입에서 topType은 이미 keyof typeof SALES_SOURCE.ORDER_METHOD 타입이어야 하는데, 여기서 as 캐스팅을 사용하고 있습니다.

타입 정의에 문제가 있거나, 불필요한 타입 캐스팅일 가능성이 있습니다. 타입 정의를 수정하거나 캐스팅이 정말 필요한지 재검토해 주세요.
frontend/src/mocks/auth/authHandler.ts:39

  • MSW 핸들러에서 passthrough()를 호출한 후 그 아래의 코드가 실행되지 않습니다. passthrough() 이후의 코드(15-39줄)는 unreachable code입니다.

디버깅/테스트 용도로 임시로 passthrough를 추가한 것이라면, 이를 제거하거나 조건부로 사용하도록 수정해 주세요.

Comment on lines +165 to +201
const newItems = structuredClone(oldData.items);

const firstItem = newItems[0];
if (!firstItem) {
return {
items: newItems,
};
}

firstItem.timeSlot2H = timeSlot2H;

const firstMenu = firstItem.menus?.[0];
if (firstMenu) {
firstMenu.menuName = menuName;
}

return {
items: newItems,
};
},
[],
);

/**
* 인기 메뉴 조합 쿼리 데이터 업데이트 함수
*/
const updatePopularMenuCombinationData = useCallback(
(response: GetDashboardPopularMenuCombinationResponseDto) =>
(oldData?: GetPopularMenuCombinationResponseDto) => {
const { firstMenuName, secondMenuName } = response;

if (!oldData) {
return oldData;
}

// 깊은 복사 후 해당 객체 수정
const newItems = structuredClone(oldData.items);
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

structuredClone을 사용할 때 주의가 필요합니다. 이 API는 모든 브라우저에서 지원되는 것은 아니며, 특히 Safari 15.3 이하 버전에서는 지원되지 않습니다.

프로젝트에서 지원하는 브라우저 범위를 확인하고, 필요시 폴리필을 추가하거나 대체 방법(예: JSON.parse/stringify, lodash cloneDeep 등)을 사용하는 것을 고려해 주세요.

Copilot uses AI. Check for mistakes.
});
}
};
}, [cardList, subscribeDashboardCardList, unsubscribeDashboardCardList]);
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

useEffect의 의존성 배열에 mutation 함수가 포함되어 있습니다. useMutation에서 반환된 mutate 함수는 매 렌더링마다 새로 생성되므로, 이를 의존성 배열에 포함하면 effect가 매번 실행되어 불필요한 구독/해지가 반복됩니다.

mutation 함수를 의존성 배열에서 제거하거나, useCallback으로 감싼 wrapper 함수를 사용하는 것이 좋습니다.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

제 의견으로는 analysis 도메인이 servicestypes 쪽에만 신설되는 게 조금 어색하게 느껴집니다.
대시보드 카드 조회 & 각 도메인 상세분석 조회에 모두 쓰이니 shared로 보내는 게 어떨까 싶습니다!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

근데 shared는 정말 모든 도메인에서 사용할 수 있어야 돼서 shared에 두기에는 애매하지 않나요 ?? 그래서 analysis 도메인을 따로 만들었습니다

Copy link
Collaborator

Choose a reason for hiding this comment

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

애매하네요... chart나 card wrapper 같은 컴포넌트는 또 shared에 있어서요~
components도 리팩터링 하면서 analysis 도메인을 만들어도 될 것 같구요

@lwjmcn
Copy link
Collaborator

lwjmcn commented Feb 20, 2026

[p1] SalesTypeContent, PaymentMethodContent, 요일별매출패턴 등 컴포넌트에 매출 데이터 없을 시 undefined 처리 필요합니다.

>
카드 {item.cardCode}
</div>
<FetchBoundary key={`dashboard-card-${item.cardCode}`}>
Copy link
Collaborator

Choose a reason for hiding this comment

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

[p4] 여기에 DefaultCardFetchBoundary 컴포넌트 사용할 수 있을 것 같네요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

반영했습니다

const getEmptyViewMessage = (
period: PeriodType<typeof PERIOD_PRESET_KEYS.today7_30>,
) => {
let dateMessage = '';
Copy link
Collaborator

Choose a reason for hiding this comment

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

[p3] dateMessage = period라고 하실 수 있습니다.

const handleSseError = useCallback(() => {
retryCountRef.current++;
// 지수 백오프
const backoff = Math.min(
Copy link
Collaborator

Choose a reason for hiding this comment

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

[p5] 지수승으로 Retry 하는 거 좋습니다~

Copy link
Collaborator

@lwjmcn lwjmcn left a comment

Choose a reason for hiding this comment

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

LGTM

@lee0jae330 lee0jae330 merged commit bd49599 into develop Feb 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feat 새로운 기능이나 서비스 로직을 추가합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FE] 대시보드 페이지 - 각 지표 카드 추가

3 participants

Comments