diff --git a/common/core/components/overview/OverviewAxisNotes.tsx b/common/core/components/overview/OverviewAxisNotes.tsx
new file mode 100644
index 00000000..e5b9a4ed
--- /dev/null
+++ b/common/core/components/overview/OverviewAxisNotes.tsx
@@ -0,0 +1,14 @@
+export function OverviewAxisNotes({
+ xAxisLabel,
+ yAxisLabel,
+}: {
+ xAxisLabel: string;
+ yAxisLabel: string;
+}) {
+ return (
+
+ {xAxisLabel}
+ {yAxisLabel}
+
+ );
+}
diff --git a/common/core/components/overview/OverviewMetric.tsx b/common/core/components/overview/OverviewMetric.tsx
new file mode 100644
index 00000000..92209381
--- /dev/null
+++ b/common/core/components/overview/OverviewMetric.tsx
@@ -0,0 +1,19 @@
+import type { ReactNode } from "react";
+
+export function OverviewMetric({
+ icon,
+ label,
+ value,
+}: {
+ icon: ReactNode;
+ label: string;
+ value: string;
+}) {
+ return (
+
+ {icon}
+ {label}
+ {value}
+
+ );
+}
diff --git a/common/core/components/overview/OverviewSelectionChips.tsx b/common/core/components/overview/OverviewSelectionChips.tsx
new file mode 100644
index 00000000..63660c3b
--- /dev/null
+++ b/common/core/components/overview/OverviewSelectionChips.tsx
@@ -0,0 +1,50 @@
+import type { ReactNode } from "react";
+
+type OverviewSelectionChipOption = {
+ id: string;
+ label: ReactNode;
+};
+
+export function OverviewSelectionChips({
+ allLabel,
+ options,
+ selectedIds,
+ onSelectAll,
+ onToggle,
+}: {
+ allLabel: string;
+ options: OverviewSelectionChipOption[];
+ selectedIds: string[];
+ onSelectAll: () => void;
+ onToggle: (id: string) => void;
+}) {
+ const isAllSelected = selectedIds.length === 0;
+
+ return (
+
+
+ {options.map((option) => (
+
+ ))}
+
+ );
+}
diff --git a/common/core/components/overview/index.ts b/common/core/components/overview/index.ts
new file mode 100644
index 00000000..b6577afa
--- /dev/null
+++ b/common/core/components/overview/index.ts
@@ -0,0 +1,3 @@
+export { OverviewMetric } from "./OverviewMetric";
+export { OverviewAxisNotes } from "./OverviewAxisNotes";
+export { OverviewSelectionChips } from "./OverviewSelectionChips";
diff --git a/common/locales/en.toml b/common/locales/en.toml
index b57b3042..0a451791 100644
--- a/common/locales/en.toml
+++ b/common/locales/en.toml
@@ -86,6 +86,21 @@ theme_toggle = "Theme Toggle"
unassigned = "Unassigned"
unknown = "Unknown"
+[ui.common.overview]
+title = "Operational Status"
+
+[ui.common.chart.period]
+day = "Day"
+month = "Month"
+week = "Week"
+
+[ui.common.chart.series_summary]
+login_users = "Login {{login}} / Users {{subjects}}"
+
+[ui.common.chart.axis]
+x = "X-axis: Period"
+y = "Y-axis: Login Requests"
+
[ui.common.badge]
admin_only = "Admin only"
command_only = "Command only"
diff --git a/common/locales/ko.toml b/common/locales/ko.toml
index c77ac6d6..249cbf04 100644
--- a/common/locales/ko.toml
+++ b/common/locales/ko.toml
@@ -86,6 +86,21 @@ theme_toggle = "테마 전환"
unassigned = "미배정"
unknown = "Unknown"
+[ui.common.overview]
+title = "운영 현황"
+
+[ui.common.chart.period]
+day = "일"
+month = "월"
+week = "주"
+
+[ui.common.chart.series_summary]
+login_users = "로그인 {{login}} / 사용자 {{subjects}}"
+
+[ui.common.chart.axis]
+x = "X축: 기간"
+y = "Y축: 로그인 요청 수"
+
[ui.common.badge]
admin_only = "Admin only"
command_only = "Command only"
diff --git a/common/locales/template.toml b/common/locales/template.toml
index 0c4f4955..cce406f5 100644
--- a/common/locales/template.toml
+++ b/common/locales/template.toml
@@ -86,6 +86,21 @@ theme_toggle = ""
unassigned = ""
unknown = ""
+[ui.common.overview]
+title = ""
+
+[ui.common.chart.period]
+day = ""
+month = ""
+week = ""
+
+[ui.common.chart.series_summary]
+login_users = ""
+
+[ui.common.chart.axis]
+x = ""
+y = ""
+
[ui.common.badge]
admin_only = ""
command_only = ""