@squadbase/vantage-template 0.2.0-dev1.20f95fa → 0.2.0-dev1.29fa6c1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/base-template/AGENTS.md +3 -3
  2. package/base-template/agents/page.md +5 -4
  3. package/base-template/bun.lock +6 -6
  4. package/base-template/package.json +2 -2
  5. package/package.json +2 -2
  6. package/ui-templates/CLAUDE.md +13 -12
  7. package/ui-templates/chart-grid/lib/mock-data.ts +0 -3
  8. package/ui-templates/chart-grid/lib/types.ts +6 -6
  9. package/ui-templates/chart-grid/pages/index.tsx +11 -161
  10. package/ui-templates/chart-grid-ja/lib/mock-data.ts +0 -3
  11. package/ui-templates/chart-grid-ja/lib/types.ts +6 -6
  12. package/ui-templates/chart-grid-ja/pages/index.tsx +11 -161
  13. package/ui-templates/funnel/lib/types.ts +2 -2
  14. package/ui-templates/funnel/pages/index.tsx +10 -88
  15. package/ui-templates/funnel-ja/lib/types.ts +2 -2
  16. package/ui-templates/funnel-ja/pages/index.tsx +10 -87
  17. package/ui-templates/kpi-chart-advanced/lib/mock-data.ts +6 -6
  18. package/ui-templates/kpi-chart-advanced/lib/types.ts +6 -7
  19. package/ui-templates/kpi-chart-advanced/pages/index.tsx +6 -117
  20. package/ui-templates/kpi-chart-advanced-ja/lib/mock-data.ts +6 -6
  21. package/ui-templates/kpi-chart-advanced-ja/lib/types.ts +6 -7
  22. package/ui-templates/kpi-chart-advanced-ja/pages/index.tsx +6 -117
  23. package/ui-templates/kpi-chart-simple/lib/types.ts +4 -4
  24. package/ui-templates/kpi-chart-simple/pages/index.tsx +4 -42
  25. package/ui-templates/kpi-chart-simple-ja/lib/types.ts +4 -4
  26. package/ui-templates/kpi-chart-simple-ja/pages/index.tsx +4 -40
  27. package/ui-templates/table-focus/lib/types.ts +3 -3
  28. package/ui-templates/table-focus/pages/index.tsx +3 -45
  29. package/ui-templates/table-focus-ja/lib/types.ts +3 -3
  30. package/ui-templates/table-focus-ja/pages/index.tsx +3 -45
@@ -3,6 +3,11 @@ import { subDays } from "date-fns"
3
3
  import { definePage } from "@squadbase/vantage"
4
4
  import {
5
5
  DashboardCardPreset,
6
+ AreaChart,
7
+ BarChart,
8
+ Heatmap,
9
+ LineChart,
10
+ ScatterChart,
6
11
  DateRangePicker,
7
12
  EChart,
8
13
  PageShell,
@@ -22,15 +27,9 @@ import {
22
27
  scatterPoints,
23
28
  radarAxes,
24
29
  heatmapCells,
25
- HEATMAP_X_AXIS,
26
- HEATMAP_Y_AXIS,
27
30
  } from "./components/chart-grid/mock-data"
28
31
  import type {
29
- TimePoint,
30
- BarPoint,
31
- ScatterPoint,
32
32
  RadarPoint,
33
- HeatmapCell,
34
33
  DashboardFilters,
35
34
  } from "./components/chart-grid/types"
36
35
 
@@ -40,86 +39,6 @@ export const page = definePage({
40
39
  "エリア/折れ線/棒/散布/レーダー/ヒートマップの6チャート格子。ヘッダーにカテゴリフィルタチップを配置。",
41
40
  })
42
41
 
43
- // ── chart helpers ───────────────────────────────────────────────────────────
44
-
45
- function getBaseGrid() {
46
- return { left: "3%", right: "4%", bottom: "10%", containLabel: true }
47
- }
48
-
49
- function formatNumber(n: number): string {
50
- const sign = n < 0 ? "-" : ""
51
- const abs = Math.abs(n)
52
- if (abs >= 100_000_000) return `${sign}${(abs / 100_000_000).toFixed(1)}億`
53
- if (abs >= 10_000) return `${sign}${(abs / 10_000).toFixed(0)}万`
54
- return n.toLocaleString("ja-JP")
55
- }
56
-
57
- // ── chart options ────────────────────────────────────────────────────────────
58
-
59
- function areaOption(data: TimePoint[]): EChartsOption {
60
- return {
61
- tooltip: { trigger: "axis" },
62
- legend: { bottom: 0 },
63
- grid: getBaseGrid(),
64
- xAxis: {
65
- type: "category",
66
- data: data.map((d) => d.date),
67
- boundaryGap: false,
68
- axisLabel: { formatter: (v: string) => v.slice(5) },
69
- },
70
- yAxis: { type: "value", axisLabel: { formatter: (v: number) => formatNumber(v) } },
71
- series: [
72
- {
73
- name: "系列A",
74
- type: "line",
75
- smooth: true,
76
- showSymbol: false,
77
- data: data.map((d) => d.series1),
78
- areaStyle: { opacity: 0.22 },
79
- },
80
- {
81
- name: "系列B",
82
- type: "line",
83
- smooth: true,
84
- showSymbol: false,
85
- data: data.map((d) => d.series2),
86
- areaStyle: { opacity: 0.14 },
87
- },
88
- ],
89
- }
90
- }
91
-
92
- function lineOption(data: TimePoint[]): EChartsOption {
93
- return {
94
- tooltip: { trigger: "axis" },
95
- legend: { bottom: 0 },
96
- grid: getBaseGrid(),
97
- xAxis: {
98
- type: "category",
99
- data: data.map((d) => d.date),
100
- boundaryGap: false,
101
- axisLabel: { formatter: (v: string) => v.slice(5) },
102
- },
103
- yAxis: { type: "value", axisLabel: { formatter: (v: number) => formatNumber(v) } },
104
- series: [
105
- {
106
- name: "系列A",
107
- type: "line",
108
- smooth: true,
109
- showSymbol: false,
110
- data: data.map((d) => d.series1),
111
- },
112
- {
113
- name: "系列B",
114
- type: "line",
115
- smooth: true,
116
- showSymbol: false,
117
- data: data.map((d) => d.series2),
118
- },
119
- ],
120
- }
121
- }
122
-
123
42
  const BAR_CATEGORIES = [
124
43
  "項目1",
125
44
  "項目2",
@@ -131,45 +50,6 @@ const BAR_CATEGORIES = [
131
50
  "項目8",
132
51
  ]
133
52
 
134
- function barOption(data: BarPoint[]): EChartsOption {
135
- return {
136
- tooltip: { trigger: "axis", axisPointer: { type: "shadow" } },
137
- grid: getBaseGrid(),
138
- xAxis: { type: "category", data: BAR_CATEGORIES },
139
- yAxis: { type: "value", axisLabel: { formatter: (v: number) => formatNumber(v) } },
140
- series: [
141
- {
142
- name: "系列A",
143
- type: "bar",
144
- data: data.map((d) => d.value),
145
- barMaxWidth: 28,
146
- },
147
- ],
148
- }
149
- }
150
-
151
- function scatterOption(data: ScatterPoint[]): EChartsOption {
152
- return {
153
- tooltip: { trigger: "item" },
154
- grid: getBaseGrid(),
155
- xAxis: { type: "value" },
156
- yAxis: { type: "value" },
157
- series: [
158
- {
159
- type: "scatter",
160
- data: data.map((p) => ({
161
- value: [p.x, p.y, p.size] as [number, number, number],
162
- label: p.label,
163
- })),
164
- symbolSize: (val: unknown) => {
165
- const arr = val as [number, number, number]
166
- return arr[2]
167
- },
168
- },
169
- ] as EChartsOption["series"],
170
- }
171
- }
172
-
173
53
  const RADAR_AXES = ["軸1", "軸2", "軸3", "軸4", "軸5", "軸6"]
174
54
 
175
55
  function radarOption(data: RadarPoint[]): EChartsOption {
@@ -200,34 +80,7 @@ function radarOption(data: RadarPoint[]): EChartsOption {
200
80
  }
201
81
  }
202
82
 
203
- function heatmapOption(
204
- data: HeatmapCell[],
205
- xAxis: string[],
206
- yAxis: string[],
207
- ): EChartsOption {
208
- const max = Math.max(...data.map((c) => c.value))
209
- return {
210
- tooltip: { position: "top" },
211
- grid: { height: "70%", top: "8%", left: "10%", right: "8%" },
212
- xAxis: { type: "category", data: xAxis, splitArea: { show: true } },
213
- yAxis: { type: "category", data: yAxis, splitArea: { show: true } },
214
- visualMap: {
215
- min: 0,
216
- max,
217
- calculable: true,
218
- orient: "horizontal",
219
- bottom: 0,
220
- },
221
- series: [
222
- {
223
- type: "heatmap",
224
- data: data.map((c) => [xAxis.indexOf(c.x), yAxis.indexOf(c.y), c.value]),
225
- label: { show: false },
226
- emphasis: { itemStyle: { shadowBlur: 8 } },
227
- },
228
- ],
229
- }
230
- }
83
+ const barRows = barSeries.map((d, i) => ({ item: BAR_CATEGORIES[i], value: d.value }))
231
84
 
232
85
  // ── page ─────────────────────────────────────────────────────────────────────
233
86
 
@@ -290,7 +143,7 @@ export default function HomePage() {
290
143
  title="トレンド (エリア)"
291
144
  description="選択期間の2系列"
292
145
  >
293
- <EChart option={areaOption(timeSeries)} height="280px" />
146
+ <AreaChart data={timeSeries} index="date" categories={["series1", "series2"]} labels={{ series1: "系列A", series2: "系列B" }} height="280px" />
294
147
  </DashboardCardPreset>
295
148
  )}
296
149
  {show("trend") && (
@@ -298,17 +151,17 @@ export default function HomePage() {
298
151
  title="トレンド (折れ線)"
299
152
  description="選択期間の2系列"
300
153
  >
301
- <EChart option={lineOption(timeSeries)} height="280px" />
154
+ <LineChart data={timeSeries} index="date" categories={["series1", "series2"]} labels={{ series1: "系列A", series2: "系列B" }} height="280px" />
302
155
  </DashboardCardPreset>
303
156
  )}
304
157
  {show("ranking") && (
305
158
  <DashboardCardPreset title="上位カテゴリ" description="値で並べ替え">
306
- <EChart option={barOption(barSeries)} height="280px" />
159
+ <BarChart data={barRows} index="item" categories={["value"]} labels={{ value: "系列A" }} showLegend={false} height="280px" />
307
160
  </DashboardCardPreset>
308
161
  )}
309
162
  {show("distribution") && (
310
163
  <DashboardCardPreset title="相関" description="各点が1項目">
311
- <EChart option={scatterOption(scatterPoints)} height="280px" />
164
+ <ScatterChart data={scatterPoints} x="x" y="y" size="size" index="label" height="280px" />
312
165
  </DashboardCardPreset>
313
166
  )}
314
167
  {show("distribution") && (
@@ -318,10 +171,7 @@ export default function HomePage() {
318
171
  )}
319
172
  {show("distribution") && (
320
173
  <DashboardCardPreset title="アクティビティ" description="セルごとの強度">
321
- <EChart
322
- option={heatmapOption(heatmapCells, HEATMAP_X_AXIS, HEATMAP_Y_AXIS)}
323
- height="280px"
324
- />
174
+ <Heatmap data={heatmapCells} x="x" y="y" value="value" xLabels={["0", "1", "2", "3", "4", "5"]} yLabels={["行7", "行6", "行5", "行4", "行3", "行2", "行1"]} height={280} />
325
175
  </DashboardCardPreset>
326
176
  )}
327
177
  </div>
@@ -1,9 +1,9 @@
1
- export interface FunnelStage {
1
+ export type FunnelStage = {
2
2
  value: number
3
3
  conversionRate: number
4
4
  }
5
5
 
6
- export interface StageRow {
6
+ export type StageRow = {
7
7
  count: number
8
8
  conversionRate: number
9
9
  avgDays: number
@@ -10,7 +10,7 @@ import {
10
10
  DashboardCardContent,
11
11
  DashboardCardPreset,
12
12
  DateRangePicker,
13
- EChart,
13
+ FunnelSteps,
14
14
  PageShell,
15
15
  PageShellHeader,
16
16
  PageShellHeading,
@@ -20,12 +20,10 @@ import {
20
20
  PageShellContent,
21
21
  Placeholder,
22
22
  } from "@squadbase/vantage/components"
23
- import type { DateRange, EChartsOption } from "@squadbase/vantage/components"
24
- import { ToggleGroup, ToggleGroupItem } from "@squadbase/vantage/ui"
23
+ import type { DateRange } from "@squadbase/vantage/components"
25
24
 
26
25
  import { StageTable } from "./components/funnel/stage-table"
27
26
  import { funnelStages, stageRows } from "./components/funnel/mock-data"
28
- import type { FunnelStage } from "./components/funnel/types"
29
27
 
30
28
  export const page = definePage({
31
29
  title: "Funnel",
@@ -36,65 +34,7 @@ export const page = definePage({
36
34
  const today = new Date()
37
35
 
38
36
  const STAGE_NAMES = ["Stage 1", "Stage 2", "Stage 3", "Stage 4", "Stage 5"]
39
-
40
- type DisplayMode = "count" | "percent"
41
-
42
- function funnelOption(
43
- data: FunnelStage[],
44
- labels: string[],
45
- display: DisplayMode,
46
- ): EChartsOption {
47
- const max = data[0]?.value ?? 0
48
-
49
- return {
50
- tooltip: { trigger: "item" },
51
- series: [
52
- {
53
- type: "funnel",
54
- orient: "horizontal",
55
- funnelAlign: "center",
56
- left: "2%",
57
- right: "2%",
58
- top: 16,
59
- bottom: 64,
60
- min: 0,
61
- max,
62
- sort: "descending",
63
- gap: 4,
64
- label: {
65
- show: true,
66
- position: "bottom",
67
- formatter: (p: unknown) => {
68
- const params = p as {
69
- name: string
70
- value: number
71
- data: { conversionRate: number; share: number }
72
- }
73
- const main =
74
- display === "percent"
75
- ? `${params.data.share.toFixed(1)}%`
76
- : params.value.toLocaleString("en-US")
77
- return `{name|${params.name}}\n{value|${main}}`
78
- },
79
- rich: {
80
- name: { fontSize: 12, fontWeight: 600, lineHeight: 16, align: "center" },
81
- value: { fontSize: 11, opacity: 0.6, lineHeight: 14, align: "center" },
82
- },
83
- },
84
- labelLine: { show: false },
85
- // No `itemStyle.color` and no `option.color`: the stages take
86
- // `--chart-1..5`, and the labels the foreground token, so the chart
87
- // rebrands with the theme (v0.2.1+).
88
- data: data.map((d, i) => ({
89
- name: labels[i] ?? "",
90
- value: d.value,
91
- conversionRate: d.conversionRate,
92
- share: (d.value / Math.max(1, max)) * 100,
93
- })),
94
- },
95
- ] as EChartsOption["series"],
96
- }
97
- }
37
+ const funnelRows = funnelStages.map((d, i) => ({ stage: STAGE_NAMES[i], value: d.value }))
98
38
 
99
39
  const summaryCards = [
100
40
  {
@@ -128,7 +68,6 @@ export default function HomePage() {
128
68
  from: subDays(today, 29),
129
69
  to: today,
130
70
  })
131
- const [display, setDisplay] = useState<DisplayMode>("count")
132
71
 
133
72
  return (
134
73
  <PageShell>
@@ -140,19 +79,6 @@ export default function HomePage() {
140
79
  </PageShellDescription>
141
80
  </PageShellHeading>
142
81
  <PageShellHeaderEnd className="flex-row items-center gap-2">
143
- {/* Base UI toggle groups are always multi-value — keep the array at length 1. */}
144
- <ToggleGroup
145
- value={[display]}
146
- onValueChange={(value) => {
147
- const next = value[0]
148
- if (next) setDisplay(next as DisplayMode)
149
- }}
150
- variant="outline"
151
- size="sm"
152
- >
153
- <ToggleGroupItem value="count">Option A</ToggleGroupItem>
154
- <ToggleGroupItem value="percent">Option B</ToggleGroupItem>
155
- </ToggleGroup>
156
82
  <DateRangePicker
157
83
  value={dateRange}
158
84
  onChange={setDateRange}
@@ -180,17 +106,13 @@ export default function HomePage() {
180
106
  </div>
181
107
 
182
108
  <div className="grid gap-4 lg:grid-cols-3">
183
- <div className="lg:col-span-2">
184
- <DashboardCardPreset
185
- title="Conversion funnel"
186
- description="Stage-by-stage conversion"
187
- >
188
- <EChart
189
- option={funnelOption(funnelStages, STAGE_NAMES, display)}
190
- height="440px"
191
- />
192
- </DashboardCardPreset>
193
- </div>
109
+ <DashboardCardPreset
110
+ className="lg:col-span-2"
111
+ title="Conversion funnel"
112
+ description="Stage-by-stage conversion"
113
+ >
114
+ <FunnelSteps data={funnelRows} index="stage" categories={["value"]} />
115
+ </DashboardCardPreset>
194
116
  <DashboardCardPreset title="Stages" description="Conversion by stage">
195
117
  <StagesSidebar />
196
118
  </DashboardCardPreset>
@@ -1,9 +1,9 @@
1
- export interface FunnelStage {
1
+ export type FunnelStage = {
2
2
  value: number
3
3
  conversionRate: number
4
4
  }
5
5
 
6
- export interface StageRow {
6
+ export type StageRow = {
7
7
  count: number
8
8
  conversionRate: number
9
9
  avgDays: number
@@ -10,7 +10,7 @@ import {
10
10
  DashboardCardContent,
11
11
  DashboardCardPreset,
12
12
  DateRangePicker,
13
- EChart,
13
+ FunnelSteps,
14
14
  PageShell,
15
15
  PageShellHeader,
16
16
  PageShellHeading,
@@ -20,12 +20,10 @@ import {
20
20
  PageShellContent,
21
21
  Placeholder,
22
22
  } from "@squadbase/vantage/components"
23
- import type { DateRange, EChartsOption } from "@squadbase/vantage/components"
24
- import { ToggleGroup, ToggleGroupItem } from "@squadbase/vantage/ui"
23
+ import type { DateRange } from "@squadbase/vantage/components"
25
24
 
26
25
  import { StageTable } from "./components/funnel/stage-table"
27
26
  import { funnelStages, stageRows } from "./components/funnel/mock-data"
28
- import type { FunnelStage } from "./components/funnel/types"
29
27
 
30
28
  export const page = definePage({
31
29
  title: "ファネル",
@@ -36,64 +34,7 @@ export const page = definePage({
36
34
  const today = new Date()
37
35
 
38
36
  const STAGE_NAMES = ["ステージ1", "ステージ2", "ステージ3", "ステージ4", "ステージ5"]
39
-
40
- type DisplayMode = "count" | "percent"
41
-
42
- function funnelOption(
43
- data: FunnelStage[],
44
- labels: string[],
45
- display: DisplayMode,
46
- ): EChartsOption {
47
- const max = data[0]?.value ?? 0
48
-
49
- return {
50
- tooltip: { trigger: "item" },
51
- series: [
52
- {
53
- type: "funnel",
54
- orient: "horizontal",
55
- funnelAlign: "center",
56
- left: "2%",
57
- right: "2%",
58
- top: 16,
59
- bottom: 64,
60
- min: 0,
61
- max,
62
- sort: "descending",
63
- gap: 4,
64
- label: {
65
- show: true,
66
- position: "bottom",
67
- formatter: (p: unknown) => {
68
- const params = p as {
69
- name: string
70
- value: number
71
- data: { conversionRate: number; share: number }
72
- }
73
- const main =
74
- display === "percent"
75
- ? `${params.data.share.toFixed(1)}%`
76
- : params.value.toLocaleString("ja-JP")
77
- return `{name|${params.name}}\n{value|${main}}`
78
- },
79
- rich: {
80
- name: { fontSize: 12, fontWeight: 600, lineHeight: 16, align: "center" },
81
- value: { fontSize: 11, opacity: 0.6, lineHeight: 14, align: "center" },
82
- },
83
- },
84
- labelLine: { show: false },
85
- // itemStyle.color も option.color も持たせない: ステージは --chart-1..5、
86
- // ラベルは文字色トークンで描かれ、テーマ差し替えに追従する (v0.2.1〜)。
87
- data: data.map((d, i) => ({
88
- name: labels[i] ?? "",
89
- value: d.value,
90
- conversionRate: d.conversionRate,
91
- share: (d.value / Math.max(1, max)) * 100,
92
- })),
93
- },
94
- ] as EChartsOption["series"],
95
- }
96
- }
37
+ const funnelRows = funnelStages.map((d, i) => ({ stage: STAGE_NAMES[i], value: d.value }))
97
38
 
98
39
  const summaryCards = [
99
40
  {
@@ -127,7 +68,6 @@ export default function HomePage() {
127
68
  from: subDays(today, 29),
128
69
  to: today,
129
70
  })
130
- const [display, setDisplay] = useState<DisplayMode>("count")
131
71
 
132
72
  return (
133
73
  <PageShell>
@@ -139,19 +79,6 @@ export default function HomePage() {
139
79
  </PageShellDescription>
140
80
  </PageShellHeading>
141
81
  <PageShellHeaderEnd className="flex-row items-center gap-2">
142
- {/* Base UI の ToggleGroup は常に配列。単一選択は長さ 1 に保つ。 */}
143
- <ToggleGroup
144
- value={[display]}
145
- onValueChange={(value) => {
146
- const next = value[0]
147
- if (next) setDisplay(next as DisplayMode)
148
- }}
149
- variant="outline"
150
- size="sm"
151
- >
152
- <ToggleGroupItem value="count">選択肢A</ToggleGroupItem>
153
- <ToggleGroupItem value="percent">選択肢B</ToggleGroupItem>
154
- </ToggleGroup>
155
82
  <DateRangePicker
156
83
  value={dateRange}
157
84
  onChange={setDateRange}
@@ -179,17 +106,13 @@ export default function HomePage() {
179
106
  </div>
180
107
 
181
108
  <div className="grid gap-4 lg:grid-cols-3">
182
- <div className="lg:col-span-2">
183
- <DashboardCardPreset
184
- title="コンバージョンファネル"
185
- description="ステージ別コンバージョン"
186
- >
187
- <EChart
188
- option={funnelOption(funnelStages, STAGE_NAMES, display)}
189
- height="440px"
190
- />
191
- </DashboardCardPreset>
192
- </div>
109
+ <DashboardCardPreset
110
+ className="lg:col-span-2"
111
+ title="コンバージョンファネル"
112
+ description="ステージ別コンバージョン"
113
+ >
114
+ <FunnelSteps data={funnelRows} index="stage" categories={["value"]} />
115
+ </DashboardCardPreset>
193
116
  <DashboardCardPreset title="ステージ" description="ステージ別コンバージョン">
194
117
  <StagesSidebar />
195
118
  </DashboardCardPreset>
@@ -40,12 +40,12 @@ export const trendSeries: TrendPoint[] = [
40
40
  ]
41
41
 
42
42
  export const comparisonSeries: ComparisonPoint[] = [
43
- { period: "2023-10", current: 308820, previous: 285196, growth: 8.28 },
44
- { period: "2023-11", current: 360871, previous: 300245, growth: 20.19 },
45
- { period: "2023-12", current: 369038, previous: 344274, growth: 7.19 },
46
- { period: "2024-01", current: 402455, previous: 338646, growth: 18.84 },
47
- { period: "2024-02", current: 443741, previous: 396096, growth: 12.03 },
48
- { period: "2024-03", current: 445883, previous: 387812, growth: 14.97 },
43
+ { period: "2023-10", current: 308820, previous: 285196 },
44
+ { period: "2023-11", current: 360871, previous: 300245 },
45
+ { period: "2023-12", current: 369038, previous: 344274 },
46
+ { period: "2024-01", current: 402455, previous: 338646 },
47
+ { period: "2024-02", current: 443741, previous: 396096 },
48
+ { period: "2024-03", current: 445883, previous: 387812 },
49
49
  ]
50
50
 
51
51
  export const breakdownSlices: BreakdownSlice[] = [
@@ -1,4 +1,4 @@
1
- export interface KpiItem {
1
+ export type KpiItem = {
2
2
  id: "revenue" | "users" | "conversion" | "aov" | "sessions"
3
3
  value: string
4
4
  change: number
@@ -7,24 +7,23 @@ export interface KpiItem {
7
7
  sparklineData: number[]
8
8
  }
9
9
 
10
- export interface ComparisonPoint {
10
+ export type ComparisonPoint = {
11
11
  period: string
12
12
  current: number
13
13
  previous: number
14
- growth: number
15
14
  }
16
15
 
17
- export interface BreakdownSlice {
16
+ export type BreakdownSlice = {
18
17
  segment: string
19
18
  value: number
20
19
  }
21
20
 
22
- export interface TrendPoint {
21
+ export type TrendPoint = {
23
22
  date: string
24
23
  value: number
25
24
  }
26
25
 
27
- export interface CampaignRow {
26
+ export type CampaignRow = {
28
27
  id: string
29
28
  name: string
30
29
  channel: string
@@ -33,6 +32,6 @@ export interface CampaignRow {
33
32
  roi: number
34
33
  }
35
34
 
36
- export interface DashboardFilters {
35
+ export type DashboardFilters = {
37
36
  dateRange: { from: Date | undefined; to: Date | undefined }
38
37
  }