From b0f573fe59a83461890ddcbfac1e64b73cfad531 Mon Sep 17 00:00:00 2001 From: YermIm Date: Thu, 14 May 2026 05:01:48 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20KPI=20=EC=B9=B4=EB=93=9C=20?= =?UTF-8?q?=EC=88=9C=EC=84=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/platform/SinglePlatformView.tsx | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/components/dashboard/platform/SinglePlatformView.tsx b/src/components/dashboard/platform/SinglePlatformView.tsx index 7b4c9062..9e543865 100644 --- a/src/components/dashboard/platform/SinglePlatformView.tsx +++ b/src/components/dashboard/platform/SinglePlatformView.tsx @@ -53,14 +53,6 @@ export default function SinglePlatformView({ if (!platformData) return []; return [ - { - title: "클릭수(CTR)", - value: platformData.clicks.toLocaleString(), - trend: { - direction: platformData.clickChangeRate >= 0 ? "up" : "down", - value: `${Math.abs(platformData.clickChangeRate * 100).toFixed(2)}%`, - }, - }, { title: "노출수", value: platformData.impressions.toLocaleString(), @@ -70,7 +62,15 @@ export default function SinglePlatformView({ }, }, { - title: "전환율(CVR)", + title: "클릭수 (CTR)", + value: platformData.clicks.toLocaleString(), + trend: { + direction: platformData.clickChangeRate >= 0 ? "up" : "down", + value: `${Math.abs(platformData.clickChangeRate * 100).toFixed(2)}%`, + }, + }, + { + title: "전환율 (CVR)", value: `${platformData.conversion}%`, trend: { direction: platformData.cvrChangeRate >= 0 ? "up" : "down", @@ -78,7 +78,7 @@ export default function SinglePlatformView({ }, }, { - title: "광고비 대비 매출(ROAS)", + title: "광고비 대비 매출 (ROAS)", value: `${platformData.ROAS}%`, trend: { direction: platformData.ROASChangeRate >= 0 ? "up" : "down", From cbd77d7e188aa67267fe9e5186361b57f1b09bcf Mon Sep 17 00:00:00 2001 From: YermIm Date: Thu, 14 May 2026 05:20:52 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=EC=83=81=EB=8B=A8=20KPI=20?= =?UTF-8?q?=EC=A7=80=ED=91=9C=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/platform/SinglePlatformView.tsx | 71 +++++++++++-------- src/hooks/dashboard/usePlatformMetrics.ts | 27 +++++++ 2 files changed, 69 insertions(+), 29 deletions(-) create mode 100644 src/hooks/dashboard/usePlatformMetrics.ts diff --git a/src/components/dashboard/platform/SinglePlatformView.tsx b/src/components/dashboard/platform/SinglePlatformView.tsx index 9e543865..28047204 100644 --- a/src/components/dashboard/platform/SinglePlatformView.tsx +++ b/src/components/dashboard/platform/SinglePlatformView.tsx @@ -1,6 +1,10 @@ import React, { useMemo } from "react"; import { twMerge } from "tailwind-merge"; +import type { TPlatformProvider } from "@/types/dashboard/platform"; + +import { usePlatformMetrics } from "@/hooks/dashboard/usePlatformMetrics"; + import Badge from "@/components/common/badge/Badge"; import Card from "@/components/common/card/Card"; import StatCard from "@/components/common/card/StatCard"; @@ -18,7 +22,6 @@ import MetaLogo from "@/assets/logo/social-logo/wordmark/meta-wordmark.svg?react import NaverLogo from "@/assets/logo/social-logo/wordmark/naver-wordmark.svg?react"; import { budgetStatusMock, - performanceEfficiencyMock, platformDailyPerformanceMock, platformTrafficMock, } from "@/pages/dashboard/platform/platformDashboard.mock"; @@ -43,11 +46,11 @@ export default function SinglePlatformView({ }: ISinglePlatformViewProps) { const [viewRange, setViewRange] = React.useState<7 | 30>(7); - const platformData = useMemo(() => { - return performanceEfficiencyMock.find( - (p) => p.provider.toUpperCase() === platform.toUpperCase(), - ); - }, [platform]); + const { + data: platformData, + isLoading: isMetricsLoading, + isError: isMetricsError, + } = usePlatformMetrics(platform.toUpperCase() as TPlatformProvider); const kpis = useMemo(() => { if (!platformData) return []; @@ -58,7 +61,7 @@ export default function SinglePlatformView({ value: platformData.impressions.toLocaleString(), trend: { direction: platformData.impressionChangeRate >= 0 ? "up" : "down", - value: `${Math.abs(platformData.impressionChangeRate * 100).toFixed(2)}%`, + value: `${Math.abs(platformData.impressionChangeRate).toFixed(2)}%`, }, }, { @@ -66,7 +69,7 @@ export default function SinglePlatformView({ value: platformData.clicks.toLocaleString(), trend: { direction: platformData.clickChangeRate >= 0 ? "up" : "down", - value: `${Math.abs(platformData.clickChangeRate * 100).toFixed(2)}%`, + value: `${Math.abs(platformData.clickChangeRate).toFixed(2)}%`, }, }, { @@ -74,7 +77,7 @@ export default function SinglePlatformView({ value: `${platformData.conversion}%`, trend: { direction: platformData.cvrChangeRate >= 0 ? "up" : "down", - value: `${Math.abs(platformData.cvrChangeRate * 100).toFixed(2)}%`, + value: `${Math.abs(platformData.cvrChangeRate).toFixed(2)}%`, }, }, { @@ -82,7 +85,7 @@ export default function SinglePlatformView({ value: `${platformData.ROAS}%`, trend: { direction: platformData.ROASChangeRate >= 0 ? "up" : "down", - value: `${Math.abs(platformData.ROASChangeRate * 100).toFixed(2)}%`, + value: `${Math.abs(platformData.ROASChangeRate).toFixed(2)}%`, }, }, ]; @@ -148,25 +151,35 @@ export default function SinglePlatformView({ {/* top */}
- {isLoading - ? Array.from({ length: 4 }).map((_, i) => ( -
- - - -
- )) - : kpis.map((kpi) => ( - - ))} + {isLoading || isMetricsLoading ? ( + Array.from({ length: 4 }).map((_, i) => ( +
+ + + +
+ )) + ) : isMetricsError ? ( +
+ 지표 데이터를 불러오지 못했습니다. +
+ ) : !platformData ? ( +
+ 표시할 지표 데이터가 없습니다. +
+ ) : ( + kpis.map((kpi) => ( + + )) + )}
{/* mid */} diff --git a/src/hooks/dashboard/usePlatformMetrics.ts b/src/hooks/dashboard/usePlatformMetrics.ts new file mode 100644 index 00000000..9777c761 --- /dev/null +++ b/src/hooks/dashboard/usePlatformMetrics.ts @@ -0,0 +1,27 @@ +import type { + IMetricsResponse, + TProviderType, +} from "@/types/dashboard/overview"; +import type { TPlatformProvider } from "@/types/dashboard/platform"; + +import { useCoreQuery } from "@/hooks/customQuery"; + +import { getOverview } from "@/api/dashboard/overview"; +import useWorkspaceStore from "@/store/useWorkspaceStore"; + +// TODO: 추후 제거 +const toBackendProvider = (provider: TPlatformProvider): TProviderType => + provider === "META" ? "KAKAO" : (provider as TProviderType); + +// 단일 플랫폼 지표 조회 +export function usePlatformMetrics(provider: TPlatformProvider) { + const orgId = useWorkspaceStore((s) => s.selectedOrgId); + + return useCoreQuery( + ["platform", "metrics", orgId, provider], + () => getOverview(orgId!, toBackendProvider(provider)), + { + enabled: !!orgId && !!provider, + }, + ); +} From c6d25aca62962043caf8841c09c1162f9aee4abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=84=9C=EC=A0=9C=EA=B2=BD?= Date: Thu, 14 May 2026 23:20:07 +0900 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20cookieDomainRewrite=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=20=EC=B6=94=EA=B0=80=EB=A1=9C=20=EA=B0=9C=EB=B0=9C=20?= =?UTF-8?q?=ED=99=98=EA=B2=BD=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EC=9C=A0?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/ads/list/CampaignDetail.tsx | 2 +- vite.config.ts | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/ads/list/CampaignDetail.tsx b/src/pages/ads/list/CampaignDetail.tsx index 9bad3eb5..e1473d5d 100644 --- a/src/pages/ads/list/CampaignDetail.tsx +++ b/src/pages/ads/list/CampaignDetail.tsx @@ -204,7 +204,7 @@ export default function CampaignDetail() {
-

+

{data.name}

{ "/api": { target: env.VITE_API_TARGET_URL, changeOrigin: true, + cookieDomainRewrite: { "*": "" }, configure(proxy) { proxy.on("proxyReq", (proxyReq) => { // 백엔드가 Origin 기반으로 CORS 차단하는 경우(예: "Invalid CORS request") From 61c68afd98affb0a1a78c25a4a2c2473787d8307 Mon Sep 17 00:00:00 2001 From: YermIm Date: Fri, 15 May 2026 19:02:00 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=ED=94=8C=EB=9E=AB=ED=8F=BC?= =?UTF-8?q?=EB=B3=84=20=EC=98=88=EC=82=B0=20=EC=86=8C=EC=A7=84=20=ED=98=84?= =?UTF-8?q?=ED=99=A9=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/platform/SinglePlatformView.tsx | 40 +++++++++---------- src/hooks/dashboard/usePlatformBudget.ts | 29 ++++++++++++++ 2 files changed, 49 insertions(+), 20 deletions(-) create mode 100644 src/hooks/dashboard/usePlatformBudget.ts diff --git a/src/components/dashboard/platform/SinglePlatformView.tsx b/src/components/dashboard/platform/SinglePlatformView.tsx index bffc1d8d..be7695e1 100644 --- a/src/components/dashboard/platform/SinglePlatformView.tsx +++ b/src/components/dashboard/platform/SinglePlatformView.tsx @@ -3,6 +3,7 @@ import { twMerge } from "tailwind-merge"; import type { TPlatformProvider } from "@/types/dashboard/platform"; +import { usePlatformBudget } from "@/hooks/dashboard/usePlatformBudget"; import { usePlatformMetrics } from "@/hooks/dashboard/usePlatformMetrics"; import Badge from "@/components/common/badge/Badge"; @@ -21,7 +22,6 @@ import GoogleLogo from "@/assets/logo/social-logo/wordmark/google-wordmark.svg?r import MetaLogo from "@/assets/logo/social-logo/wordmark/meta-wordmark.svg?react"; import NaverLogo from "@/assets/logo/social-logo/wordmark/naver-wordmark.svg?react"; import { - budgetStatusMock, platformDailyPerformanceMock, platformTrafficMock, } from "@/pages/dashboard/platform/platformDashboard.mock"; @@ -93,19 +93,11 @@ export default function SinglePlatformView({ const logoInfo = PLATFORM_LOGOS[platform.toUpperCase()]; - const budget = useMemo(() => { - const data = budgetStatusMock.find( - (b) => b.providerType.toUpperCase() === platform.toUpperCase(), - ); - if (!data) return null; - - return { - totalBudget: data.totalBudget, - spent: data.totalSpend, - warningThreshold: 50, - dangerThreshold: 75, - }; - }, [platform]); + const { + data: budget, + isLoading: isBudgetLoading, + isError: isBudgetError, + } = usePlatformBudget(platform.toUpperCase() as TPlatformProvider); const budgetPct = budget ? Math.round((budget.spent / budget.totalBudget) * 100) @@ -163,11 +155,11 @@ export default function SinglePlatformView({
)) ) : isMetricsError ? ( -
+
지표 데이터를 불러오지 못했습니다.
) : !platformData ? ( -
+
표시할 지표 데이터가 없습니다.
) : ( @@ -226,13 +218,21 @@ export default function SinglePlatformView({ ) } > - {budget ? ( -
+ {isLoading || isBudgetLoading ? ( +
+ +
+ ) : isBudgetError ? ( +
+ 예산 데이터를 불러오지 못했습니다. +
+ ) : budget ? ( +
) : ( -
- 데이터가 없습니다. +
+ 표시할 예산 데이터가 없습니다.
)} diff --git a/src/hooks/dashboard/usePlatformBudget.ts b/src/hooks/dashboard/usePlatformBudget.ts new file mode 100644 index 00000000..90d0b5ba --- /dev/null +++ b/src/hooks/dashboard/usePlatformBudget.ts @@ -0,0 +1,29 @@ +import type { TProviderType } from "@/types/dashboard/overview"; +import type { TPlatformProvider } from "@/types/dashboard/platform"; + +import { useCoreQuery } from "@/hooks/customQuery"; + +import { getBudget } from "@/api/dashboard/overview"; +import useWorkspaceStore from "@/store/useWorkspaceStore"; + +const WARNING_THRESHOLD = 50; +const DANGER_THRESHOLD = 75; + +// 단일 플랫폼 예산 소진 현황 +export function usePlatformBudget(provider: TPlatformProvider) { + const orgId = useWorkspaceStore((s) => s.selectedOrgId); + + return useCoreQuery( + ["platform", "budget", orgId, provider], + () => getBudget(orgId!, provider as TProviderType), + { + enabled: !!orgId && !!provider, + select: (data) => ({ + totalBudget: data.totalBudget, + spent: data.totalSpend, + warningThreshold: WARNING_THRESHOLD, + dangerThreshold: DANGER_THRESHOLD, + }), + }, + ); +} From 6cead26adb21d5ecafb3d59f8f2fbe99cee42950 Mon Sep 17 00:00:00 2001 From: YermIm Date: Fri, 15 May 2026 19:07:51 +0900 Subject: [PATCH 5/8] =?UTF-8?q?fix:=20=ED=94=8C=EB=9E=AB=ED=8F=BC=EB=B3=84?= =?UTF-8?q?=20KPI=20API=20providerType=20META=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/dashboard/usePlatformMetrics.ts | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/hooks/dashboard/usePlatformMetrics.ts b/src/hooks/dashboard/usePlatformMetrics.ts index 9777c761..f4c90ba6 100644 --- a/src/hooks/dashboard/usePlatformMetrics.ts +++ b/src/hooks/dashboard/usePlatformMetrics.ts @@ -9,17 +9,13 @@ import { useCoreQuery } from "@/hooks/customQuery"; import { getOverview } from "@/api/dashboard/overview"; import useWorkspaceStore from "@/store/useWorkspaceStore"; -// TODO: 추후 제거 -const toBackendProvider = (provider: TPlatformProvider): TProviderType => - provider === "META" ? "KAKAO" : (provider as TProviderType); - // 단일 플랫폼 지표 조회 export function usePlatformMetrics(provider: TPlatformProvider) { const orgId = useWorkspaceStore((s) => s.selectedOrgId); return useCoreQuery( ["platform", "metrics", orgId, provider], - () => getOverview(orgId!, toBackendProvider(provider)), + () => getOverview(orgId!, provider as TProviderType), { enabled: !!orgId && !!provider, }, From ab34f993458834105f53c9a9d241451779c9bc91 Mon Sep 17 00:00:00 2001 From: YermIm Date: Fri, 15 May 2026 21:27:51 +0900 Subject: [PATCH 6/8] =?UTF-8?q?refactor:=20SinglePlatformView=20KPI=20tren?= =?UTF-8?q?d=20as=20any=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dashboard/platform/SinglePlatformView.tsx | 29 +++++++------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/components/dashboard/platform/SinglePlatformView.tsx b/src/components/dashboard/platform/SinglePlatformView.tsx index be7695e1..a62a332d 100644 --- a/src/components/dashboard/platform/SinglePlatformView.tsx +++ b/src/components/dashboard/platform/SinglePlatformView.tsx @@ -8,7 +8,7 @@ import { usePlatformMetrics } from "@/hooks/dashboard/usePlatformMetrics"; import Badge from "@/components/common/badge/Badge"; import Card from "@/components/common/card/Card"; -import StatCard from "@/components/common/card/StatCard"; +import StatCard, { type ITrend } from "@/components/common/card/StatCard"; import ChartLegend from "@/components/common/chart/ChartLegend"; import { Skeleton } from "@/components/common/skeleton/Skeleton"; import BudgetGaugeChart, { @@ -52,6 +52,11 @@ export default function SinglePlatformView({ isError: isMetricsError, } = usePlatformMetrics(platform.toUpperCase() as TPlatformProvider); + const toTrend = (changeRate: number): ITrend => ({ + direction: changeRate >= 0 ? "up" : "down", + value: `${Math.abs(changeRate).toFixed(2)}%`, + }); + const kpis = useMemo(() => { if (!platformData) return []; @@ -59,34 +64,22 @@ export default function SinglePlatformView({ { title: "노출수", value: platformData.impressions.toLocaleString(), - trend: { - direction: platformData.impressionChangeRate >= 0 ? "up" : "down", - value: `${Math.abs(platformData.impressionChangeRate).toFixed(2)}%`, - }, + trend: toTrend(platformData.impressionChangeRate), }, { title: "클릭수 (CTR)", value: platformData.clicks.toLocaleString(), - trend: { - direction: platformData.clickChangeRate >= 0 ? "up" : "down", - value: `${Math.abs(platformData.clickChangeRate).toFixed(2)}%`, - }, + trend: toTrend(platformData.clickChangeRate), }, { title: "전환율 (CVR)", value: `${platformData.conversion}%`, - trend: { - direction: platformData.cvrChangeRate >= 0 ? "up" : "down", - value: `${Math.abs(platformData.cvrChangeRate).toFixed(2)}%`, - }, + trend: toTrend(platformData.cvrChangeRate), }, { title: "광고비 대비 매출 (ROAS)", value: `${platformData.ROAS}%`, - trend: { - direction: platformData.ROASChangeRate >= 0 ? "up" : "down", - value: `${Math.abs(platformData.ROASChangeRate).toFixed(2)}%`, - }, + trend: toTrend(platformData.ROASChangeRate), }, ]; }, [platformData]); @@ -168,7 +161,7 @@ export default function SinglePlatformView({ key={kpi.title} title={kpi.title} value={kpi.value} - trend={kpi.trend as any} + trend={kpi.trend} /> )) )} From ec80495cf4e744a5e4c856ed3e450946a5c17129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=84=9C=EC=A0=9C=EA=B2=BD?= Date: Sat, 16 May 2026 18:23:43 +0900 Subject: [PATCH 7/8] =?UTF-8?q?refactor:=20kakao=20->=20meta=20=ED=94=8C?= =?UTF-8?q?=EB=9E=AB=ED=8F=BC=20=EC=B9=B4=EB=93=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/dashboard/platform/PlatformRoasTable.tsx | 6 +++--- src/hooks/dashboard/useOverviewRoasRankings.ts | 9 +++++---- src/types/dashboard/overview.ts | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/components/dashboard/platform/PlatformRoasTable.tsx b/src/components/dashboard/platform/PlatformRoasTable.tsx index e5f42cbe..181cd0e4 100644 --- a/src/components/dashboard/platform/PlatformRoasTable.tsx +++ b/src/components/dashboard/platform/PlatformRoasTable.tsx @@ -5,13 +5,13 @@ import type { IPlatformRankingItem } from "@/types/dashboard/overview"; import { TrendBadge } from "@/components/common/card/StatCard"; import GoogleLogo from "@/assets/logo/social-logo/circle/google-circle.svg?react"; +import MetaLogo from "@/assets/logo/social-logo/circle/meta-circle.svg?react"; import NaverLogo from "@/assets/logo/social-logo/circle/naver-circle.svg?react"; -import KakaoLogo from "@/assets/logo/social-logo/plain/kakao.svg?react"; const platformLogoMap = { Google: , NAVER: , - Kakao: , + Meta: , }; type TPlatformName = keyof typeof platformLogoMap; @@ -19,7 +19,7 @@ type TPlatformName = keyof typeof platformLogoMap; const providerDisplayMap: Record = { GOOGLE: "Google", NAVER: "NAVER", - KAKAO: "Kakao", + META: "Meta", }; function getDisplayName(provider: string): string { diff --git a/src/hooks/dashboard/useOverviewRoasRankings.ts b/src/hooks/dashboard/useOverviewRoasRankings.ts index ab9d1d86..0504864f 100644 --- a/src/hooks/dashboard/useOverviewRoasRankings.ts +++ b/src/hooks/dashboard/useOverviewRoasRankings.ts @@ -8,17 +8,17 @@ import { useCoreQuery } from "@/hooks/customQuery"; import { getOverview, getRoasRankings } from "@/api/dashboard/overview"; import useWorkspaceStore from "@/store/useWorkspaceStore"; -const PROVIDERS: TProviderType[] = ["GOOGLE", "NAVER", "KAKAO"]; +const PROVIDERS: TProviderType[] = ["GOOGLE", "NAVER", "META"]; -// 플랫폼별 ROAS 순위 + CTR/CVR 지표 병렬 조회 후 병합 export function useOverviewRoasRankings() { const orgId = useWorkspaceStore((s) => s.selectedOrgId); return useCoreQuery( ["overview", "roasRankings", orgId], async (): Promise => { + // ROAS 순위 + 플랫폼별 지표 병렬 조회 const [rankingsRes, ...metricsResults] = await Promise.all([ - // TODO: 백엔드 빈 배열 이슈 확인용 임시 날짜 범위 — 정상화 후 제거 + // TODO: 백엔드 빈 배열 이슈 — 임시 날짜 범위 getRoasRankings(orgId!, { startDate: "2026-01-22", endDate: "2026-03-22", @@ -26,13 +26,14 @@ export function useOverviewRoasRankings() { ...PROVIDERS.map((p) => getOverview(orgId!, p).catch(() => null)), ]); + // provider → metrics 매핑 const metricsMap = Object.fromEntries( PROVIDERS.map((p, i) => [p, metricsResults[i]]), ); return rankingsRes.rankings.map((item) => { const metrics = metricsMap[item.provider.toUpperCase()]; - // CTR = 클릭수 / 노출수 * 100 + // CTR = 클릭수 ÷ 노출수 × 100 const clickRate = metrics && metrics.impressions > 0 ? (metrics.clicks / metrics.impressions) * 100 diff --git a/src/types/dashboard/overview.ts b/src/types/dashboard/overview.ts index abe7ee66..a6b50a59 100644 --- a/src/types/dashboard/overview.ts +++ b/src/types/dashboard/overview.ts @@ -1,5 +1,5 @@ // 광고 플랫폼 종류 -export type TProviderType = "KAKAO" | "NAVER" | "GOOGLE"; +export type TProviderType = "META" | "NAVER" | "GOOGLE"; // 전체 지표 집계 응답 export interface IMetricsResponse { From 7ebdd6720d616f20dedb269abdfddf3e21af2df9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=84=9C=EC=A0=9C=EA=B2=BD?= Date: Sat, 16 May 2026 18:31:37 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor:=20=EB=8C=80=EC=8B=9C=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EA=B4=80=EB=A0=A8=20=ED=9B=85=20meta=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/dashboard/usePlatformAdCount.ts | 20 ++----------------- src/hooks/dashboard/usePlatformPerformance.ts | 13 +++--------- .../dashboard/usePlatformRoasRankings.ts | 11 ++-------- src/types/dashboard/platform.ts | 2 +- 4 files changed, 8 insertions(+), 38 deletions(-) diff --git a/src/hooks/dashboard/usePlatformAdCount.ts b/src/hooks/dashboard/usePlatformAdCount.ts index 93dc3024..64cb87b8 100644 --- a/src/hooks/dashboard/usePlatformAdCount.ts +++ b/src/hooks/dashboard/usePlatformAdCount.ts @@ -1,17 +1,10 @@ -import type { - IAdStatusData, - TPlatformProvider, -} from "@/types/dashboard/platform"; +import type { IAdStatusData } from "@/types/dashboard/platform"; import { useCoreQuery } from "@/hooks/customQuery"; import { getAdCount } from "@/api/dashboard/platform"; import useWorkspaceStore from "@/store/useWorkspaceStore"; -// TODO: 추후 제거 -const normalizeProvider = (provider: string): TPlatformProvider => - provider === "KAKAO" ? "META" : (provider as TPlatformProvider); - // 광고 소재 현황 export function usePlatformAdCount() { const orgId = useWorkspaceStore((s) => s.selectedOrgId); @@ -19,15 +12,6 @@ export function usePlatformAdCount() { return useCoreQuery( ["platform", "adCount", orgId], () => getAdCount(orgId!), - { - enabled: !!orgId, - select: (data): IAdStatusData => ({ - ...data, - providerCount: data.providerCount.map((item) => ({ - ...item, - provider: normalizeProvider(item.provider), - })), - }), - }, + { enabled: !!orgId }, ); } diff --git a/src/hooks/dashboard/usePlatformPerformance.ts b/src/hooks/dashboard/usePlatformPerformance.ts index 3c73e39e..5803056b 100644 --- a/src/hooks/dashboard/usePlatformPerformance.ts +++ b/src/hooks/dashboard/usePlatformPerformance.ts @@ -1,19 +1,12 @@ import type { TProviderType } from "@/types/dashboard/overview"; -import type { - IPlatformPerformance, - TPlatformProvider, -} from "@/types/dashboard/platform"; +import type { IPlatformPerformance } from "@/types/dashboard/platform"; import { useCoreQuery } from "@/hooks/customQuery"; import { getOverview } from "@/api/dashboard/overview"; import useWorkspaceStore from "@/store/useWorkspaceStore"; -// TODO: 추후 제거 -const normalizeProvider = (provider: string): TPlatformProvider => - provider === "KAKAO" ? "META" : (provider as TPlatformProvider); - -const PROVIDERS: TProviderType[] = ["GOOGLE", "NAVER", "KAKAO"]; +const PROVIDERS: TProviderType[] = ["GOOGLE", "NAVER", "META"]; // 플랫폼별 성과 효율 (3개 플랫폼 병렬 조회 후 병합) export function usePlatformPerformance() { @@ -26,7 +19,7 @@ export function usePlatformPerformance() { PROVIDERS.map((provider) => getOverview(orgId!, provider).then((metrics) => ({ ...metrics, - provider: normalizeProvider(provider), + provider, })), ), ); diff --git a/src/hooks/dashboard/usePlatformRoasRankings.ts b/src/hooks/dashboard/usePlatformRoasRankings.ts index 589b5a10..a32b12ec 100644 --- a/src/hooks/dashboard/usePlatformRoasRankings.ts +++ b/src/hooks/dashboard/usePlatformRoasRankings.ts @@ -4,15 +4,12 @@ import { useCoreQuery } from "@/hooks/customQuery"; import { getRoasRankings } from "@/api/dashboard/overview"; import useWorkspaceStore from "@/store/useWorkspaceStore"; -// TODO: 추후 제거 -const normalizeProvider = (provider: string): string => - provider === "KAKAO" ? "META" : provider; + // ROAS 성과 순위 (상위 3개) export function usePlatformRoasRankings() { const orgId = useWorkspaceStore((s) => s.selectedOrgId); return useCoreQuery( ["platform", "roasRankings", orgId], - // TODO: 추후 제거 () => getRoasRankings(orgId!, { startDate: "2026-01-22", @@ -20,11 +17,7 @@ export function usePlatformRoasRankings() { }), { enabled: !!orgId, - select: (data): IRoasRanking[] => - data.rankings.map((item) => ({ - ...item, - provider: normalizeProvider(item.provider), - })), + select: (data): IRoasRanking[] => data.rankings, }, ); } diff --git a/src/types/dashboard/platform.ts b/src/types/dashboard/platform.ts index 0a5a0fd8..c7eab7df 100644 --- a/src/types/dashboard/platform.ts +++ b/src/types/dashboard/platform.ts @@ -1,6 +1,6 @@ import type { TProviderType } from "./overview"; -export type TPlatformProvider = TProviderType | "META"; +export type TPlatformProvider = TProviderType; export const PLATFORM_MAP: Record = { GOOGLE: "Google",