diff --git a/apps/monitor-web/src/App.tsx b/apps/monitor-web/src/App.tsx index ee37c8d..cf9d7a7 100644 --- a/apps/monitor-web/src/App.tsx +++ b/apps/monitor-web/src/App.tsx @@ -1,14 +1,21 @@ +import { useRef } from "react"; import { Routes, Route } from "react-router-dom"; import { Dashboard, Login, ErrorLog, ApiDetail, ApiEdit, ErrorDetail, NotFound } from "./pages"; import { Sidebar, ToastContainer } from "./layouts"; -import { AuthRoute } from "./components"; +import { AuthRoute, ScrollToTop } from "./components"; export default function App() { + const mainRef = useRef(null); + return (
-
+
+
} path="/" /> diff --git a/apps/monitor-web/src/components/routes/ScrollToTop.tsx b/apps/monitor-web/src/components/routes/ScrollToTop.tsx new file mode 100644 index 0000000..0d21cff --- /dev/null +++ b/apps/monitor-web/src/components/routes/ScrollToTop.tsx @@ -0,0 +1,29 @@ +import { useEffect, type RefObject } from "react"; +import { useLocation } from "react-router-dom"; + +/** + * 라우트 변경 시 지정한 스크롤 컨테이너의 위치를 최상단으로 초기화하는 컴포넌트입니다. + * + * @remarks + * - `window`가 아니라 `targetRef`로 전달된 스크롤 컨테이너를 직접 제어합니다. + * - `pathname` 변경 시 `top`, `left` 위치를 0으로 되돌립니다. + * - 화면에 렌더링되는 UI 없이 라우팅 사이드 이펙트만 처리합니다. + * + * @author junyeol + */ + +interface ScrollToTopProps { + targetRef: RefObject; +} + +const ScrollToTop = ({ targetRef }: ScrollToTopProps) => { + const { pathname } = useLocation(); + + useEffect(() => { + targetRef.current?.scrollTo({ top: 0, left: 0 }); + }, [pathname, targetRef]); + + return null; +}; + +export default ScrollToTop; diff --git a/apps/monitor-web/src/components/routes/index.ts b/apps/monitor-web/src/components/routes/index.ts index d571802..e036f29 100644 --- a/apps/monitor-web/src/components/routes/index.ts +++ b/apps/monitor-web/src/components/routes/index.ts @@ -1 +1,2 @@ export { default as AuthRoute } from "./AuthRoute"; +export { default as ScrollToTop } from "./ScrollToTop"; diff --git a/apps/monitor-web/src/pages/Dashboard/_components/DashboardApiList.tsx b/apps/monitor-web/src/pages/Dashboard/_components/DashboardApiList.tsx index 0602b34..b78fdff 100644 --- a/apps/monitor-web/src/pages/Dashboard/_components/DashboardApiList.tsx +++ b/apps/monitor-web/src/pages/Dashboard/_components/DashboardApiList.tsx @@ -4,6 +4,7 @@ import { Badge } from "@/components"; import { MOCK_DASHBOARD_API_LIST } from "@/mock"; import type { ApiStatus } from "@/types"; import type { ApiListItem } from "../_types"; +import { useNavigate } from "react-router-dom"; const API_STATUS_LABEL: Record = { healthy: "정상", @@ -60,6 +61,12 @@ const API_TABLE_COLUMNS: { ]; const DashboardApiList = () => { + const navigate = useNavigate(); + + const handleGoApiDetail = (apiId: string) => { + navigate(`/api/${apiId}`); + }; + return (

전체 API 목록

@@ -78,7 +85,12 @@ const DashboardApiList = () => { {MOCK_DASHBOARD_API_LIST.map((api) => ( - + handleGoApiDetail(api.id)} + > {API_TABLE_COLUMNS.map((column) => ( { innerRadius={80} outerRadius={120} paddingAngle={4} + pointerEvents="none" > {CHART_DATA.map((entry) => (