Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions src/types/timeline/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*타임라인 추적 지표*/
export const TIMELINE_METRICS = [
"CLICK",
"CONVERSION",
"IMPRESSION",
"ROAS",
] as const;
export type TTimelineMetric = (typeof TIMELINE_METRICS)[number];

/*성과 상태*/
export const TIMELINE_PERFORMANCE_STATUS = [
"ON_TRACK",
"AT_RISK",
"OFF_TRACK",
] as const;
export type TTimelinePerformanceStatus =
(typeof TIMELINE_PERFORMANCE_STATUS)[number];

/*비교 기간 타입*/
export const TIMELINE_COMPARISON_PERIOD_TYPES = [
"LAST_WEEK",
"LAST_MONTH",
"PREVIOUS_PERIOD",
] as const;
export type TTimelineComparisonPeriodType =
(typeof TIMELINE_COMPARISON_PERIOD_TYPES)[number];

export interface ITimelineListItem {
timelineId: number;
name: string;
startDate: string;
endDate: string;
performanceStatus: TTimelinePerformanceStatus;
}

export interface ITimelineDailyTrend {
date: string;
clicks: number;
conversions: number;
impressions: number;
roas: number;
}

export interface ITimelinePlatformContribution {
platform: string;
contributionRate: number;
}
Comment thread
jjjsun marked this conversation as resolved.
Resolved

export interface ITimelineDetail {
timelineId: number;
name: string;
startDate: string;
endDate: string;
performanceStatus: TTimelinePerformanceStatus;
metrics: TTimelineMetric[];
summary: string;
dailyTrend: ITimelineDailyTrend[];
platformContributions: ITimelinePlatformContribution[];
}

/* Request body*/
export interface ITimelineUpsertRequest {
name: string;
startDate: string;
endDate: string;
metrics: TTimelineMetric[];
comparisonPeriodType: TTimelineComparisonPeriodType;
}

export interface ITimelineMutationResponse {
timelineId: number;
name: string;
startDate: string;
endDate: string;
metrics: TTimelineMetric[];
comparisonStartDate: string;
comparisonEndDate: string;
performanceStatus: TTimelinePerformanceStatus;
createdAt: string;
}

/*DELETE / summary 요청 등 빈 data*/
export type TTimelineEmptyResponse = Record<string, never>;
21 changes: 21 additions & 0 deletions src/types/timeline/form.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import type {
TTimelineComparisonPeriodType,
TTimelineMetric,
} from "@/types/timeline/api";

export interface ITimelineFormValues {
name: string;
startDate: string;
endDate: string;
metrics: TTimelineMetric[];
comparisonPeriodType: TTimelineComparisonPeriodType;
}

/*후속 zod 연동 전 기본값*/
export const TIMELINE_FORM_DEFAULT_VALUES: ITimelineFormValues = {
name: "",
startDate: "",
endDate: "",
metrics: ["CLICK"],
comparisonPeriodType: "LAST_WEEK",
};
26 changes: 26 additions & 0 deletions src/types/timeline/summary.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import type { TProviderType } from "@/types/dashboard/provider";
import type { TTimelineMetric } from "@/types/timeline/api";

/*패널 상단 KPI 카드 한개*/
export interface ITimelineSummaryMetric {
metric: TTimelineMetric;
label: string; //클릭, 전환 등 UI 라벨
value: number; //실제 값
unit?: string; // %, 회
changeRate?: number; //전기 대비 (-0.05 = -5%)
}

/*플랫폼 기여도*/
export interface ITimelineSummaryPlatformShare {
provider: TProviderType;
contributionRate: number; /*기여도*/
}

/*성과 요약 패널 전체*/
export interface ITimelineSummaryPanelData {
timelineName: string;
periodLabel: string;
aiSummary: string;
metrics: ITimelineSummaryMetric[];
platformShare: ITimelineSummaryPlatformShare[];
}
141 changes: 141 additions & 0 deletions src/types/timeline/timeline.mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
import type {
ITimelineDetail,
ITimelineListItem,
ITimelineMutationResponse,
} from "@/types/timeline/api";
import type { ITimelineSummaryPanelData } from "@/types/timeline/summary";
import type { ITimelineGridData } from "@/types/timeline/ui";

/*GET /timeline 목록 mock*/
export const TIMELINE_LIST_MOCK: ITimelineListItem[] = [
{
timelineId: 1,
name: "6월 봄 프로모션",
startDate: "2026-06-01",
endDate: "2026-06-30",
performanceStatus: "ON_TRACK",
},
{
timelineId: 2,
name: "리타겟팅 집중 기간",
startDate: "2026-06-10",
endDate: "2026-06-30",
performanceStatus: "AT_RISK",
},
];

/*GET /timeline/{id} 상세 mock*/
export const TIMELINE_DETAIL_MOCK: ITimelineDetail = {
timelineId: 1,
name: "6월 봄 프로모션",
startDate: "2026-06-01",
endDate: "2026-06-30",
performanceStatus: "ON_TRACK",
metrics: ["CLICK", "CONVERSION", "ROAS"],
summary:
"Google Ads 전환이 전주 대비 12% 상승했습니다. Meta는 노출은 늘었으나 ROAS가 소폭 하락했습니다.",
dailyTrend: [
{
date: "2026-06-18",
clicks: 1240,
conversions: 86,
impressions: 45200,
roas: 3.2,
},
{
date: "2026-06-19",
clicks: 1310,
conversions: 91,
impressions: 46800,
roas: 3.4,
},
{
date: "2026-06-20",
clicks: 1180,
conversions: 78,
impressions: 44100,
roas: 2.9,
},
],
platformContributions: [
{ platform: "GOOGLE", contributionRate: 0.52 },
{ platform: "META", contributionRate: 0.31 },
{ platform: "NAVER", contributionRate: 0.17 },
],
};

/*POST 생성 응답 mock*/
export const TIMELINE_CREATE_RESPONSE_MOCK: ITimelineMutationResponse = {
timelineId: 3,
name: "신규 타임라인",
startDate: "2026-06-01",
endDate: "2026-06-30",
metrics: ["CLICK"],
comparisonStartDate: "2026-05-25",
comparisonEndDate: "2026-05-31",
performanceStatus: "ON_TRACK",
createdAt: "2026-06-20T07:58:24.795Z",
};

/*UI 그리드 mock*/
export const TIMELINE_GRID_MOCK: ITimelineGridData = {
viewUnit: "WEEK",
periodLabel: "27 Dec - 4 Jan",
columns: [
{ day: "M", date: 30, isWeekend: false },
{ day: "T", date: 31, isWeekend: false },
{ day: "W", date: 1, isWeekend: false },
{ day: "T", date: 2, isWeekend: false, isToday: true },
{ day: "F", date: 3, isWeekend: false },
{ day: "S", date: 4, isWeekend: true },
{ day: "S", date: 5, isWeekend: true },
],
Comment thread
jjjsun marked this conversation as resolved.
Resolved
bars: [
{
id: 1,
title: "봄 프로모션 캠페인",
subtitle: "Google Ads 전환",
provider: "GOOGLE",
colStart: 3.2,
colEnd: 9,
row: 1,
colorClass: "bg-primary-300",
performanceStatus: "ON_TRACK",
},
{
id: 2,
title: "리타겟팅 캠페인",
subtitle: "META 트래픽",
provider: "META",
colStart: 8.9,
colEnd: 15.3,
row: 2,
colorClass: "bg-primary-400",
performanceStatus: "AT_RISK",
},
],
};

/*성과 요약 패널 mock*/
export const TIMELINE_SUMMARY_PANEL_MOCK: ITimelineSummaryPanelData = {
timelineName: TIMELINE_DETAIL_MOCK.name,
periodLabel: "2026.06.01 ~ 2026.06.30",
aiSummary: TIMELINE_DETAIL_MOCK.summary,
metrics: [
{ metric: "CLICK", label: "클릭", value: 3730, changeRate: 0.08 },
{ metric: "CONVERSION", label: "전환", value: 255, changeRate: 0.12 },
{ metric: "IMPRESSION", label: "노출", value: 136100, changeRate: 0.05 },
{
metric: "ROAS",
label: "ROAS",
value: 3.17,
unit: "x",
changeRate: -0.03,
},
],
platformShare: [
{ provider: "GOOGLE", contributionRate: 0.52 },
{ provider: "META", contributionRate: 0.31 },
{ provider: "NAVER", contributionRate: 0.17 },
],
};
35 changes: 35 additions & 0 deletions src/types/timeline/ui.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { TProviderType } from "@/types/dashboard/provider";
import type { TTimelinePerformanceStatus } from "@/types/timeline/api";

export type TTimelineViewUnit = "DAY" | "WEEK" | "MONTH";

/*날짜 축 한칸*/
export interface ITimelineGridColumn {
day: string;
date: number;
isWeekend: boolean;
isToday?: boolean;
/*원본 날짜*/
isoDate?: string;
}

/*타임라인 위 캠페인 바*/
export interface ITimelineCampaignBar {
id: number;
title: string;
subtitle: string;
provider?: TProviderType;
colStart: number; //그리드 시작 위치
colEnd: number;
row: number;
colorClass: string;
performanceStatus?: TTimelinePerformanceStatus;
}

/*그리드 + 바 묶음*/
export interface ITimelineGridData {
viewUnit: TTimelineViewUnit;
periodLabel: string;
columns: ITimelineGridColumn[];
bars: ITimelineCampaignBar[];
}
Loading