diff --git a/apps/cs/src/app/index.tsx b/apps/cs/src/app/index.tsx index 692b55ef0..6ba1e325a 100644 --- a/apps/cs/src/app/index.tsx +++ b/apps/cs/src/app/index.tsx @@ -2,8 +2,8 @@ import "./styles/base.css"; import "./styles/components.css"; import "@fontsource-variable/noto-sans-kr"; -import { AppProvider } from "./providers"; import { cookies } from "next/headers"; +import { AppProvider } from "./providers/app-provider"; const App = async ({ children }: Readonly<{ children: React.ReactNode }>) => { const theme = (await cookies()).get("site-theme-key"); diff --git a/apps/cs/src/app/providers/index.ts b/apps/cs/src/app/providers/index.ts deleted file mode 100644 index 15f99b7fd..000000000 --- a/apps/cs/src/app/providers/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { AppProvider } from "./app-provider"; diff --git a/apps/cs/src/pages/user-statistics/api/connection-log-service.ts b/apps/cs/src/entities/connection-log/api/connection-log-service.ts similarity index 63% rename from apps/cs/src/pages/user-statistics/api/connection-log-service.ts rename to apps/cs/src/entities/connection-log/api/connection-log-service.ts index 0e2daeb5b..0b4cc55ad 100644 --- a/apps/cs/src/pages/user-statistics/api/connection-log-service.ts +++ b/apps/cs/src/entities/connection-log/api/connection-log-service.ts @@ -2,17 +2,19 @@ import { client } from "@/shared/api"; import { ENDPOINT } from "@/shared/config"; import { type ConnectionLogParams, - type ConnectionLogList, type ConnectionStatisticsParams, type ConnectionStatistics, type ConnectionLogService, + type ConnectionLogPageList, + type ConnectionLogPayload, + type ConnectionLog, } from "../model/connection-log-interface"; class ConnectionLogApiService implements ConnectionLogService { - async getConnectionLog( + async getConnectionLogPage( params: ConnectionLogParams, - ): Promise { - const response = await client.get( + ): Promise { + const response = await client.get( `${ENDPOINT.CMS_SERVICE.CONNECTION_LOG}`, { params }, ); @@ -28,6 +30,16 @@ class ConnectionLogApiService implements ConnectionLogService { ); return response.data; } + + async saveConnectionLog( + payload: ConnectionLogPayload, + ): Promise { + const response = await client.post( + `${ENDPOINT.CMS_SERVICE.CONNECTION_LOG}`, + payload, + ); + return response.data; + } } export const ConnectionLogApi = new ConnectionLogApiService(); diff --git a/apps/cs/src/entities/connection-log/index.ts b/apps/cs/src/entities/connection-log/index.ts new file mode 100644 index 000000000..d9c61a988 --- /dev/null +++ b/apps/cs/src/entities/connection-log/index.ts @@ -0,0 +1,6 @@ +export { ConnectionLogApi } from "./api/connection-log-service"; +export type { + ConnectionLog, + ConnectionStatistics, + ConnectionStatisticsParams, +} from "./model/connection-log-interface"; diff --git a/apps/cs/src/pages/user-statistics/model/connection-log-interface.ts b/apps/cs/src/entities/connection-log/model/connection-log-interface.ts similarity index 74% rename from apps/cs/src/pages/user-statistics/model/connection-log-interface.ts rename to apps/cs/src/entities/connection-log/model/connection-log-interface.ts index 6fbf4dc15..aed70873f 100644 --- a/apps/cs/src/pages/user-statistics/model/connection-log-interface.ts +++ b/apps/cs/src/entities/connection-log/model/connection-log-interface.ts @@ -22,11 +22,24 @@ export interface ConnectionLog { menuCd: number; siteId: string; urlPath: string; +} + +export interface ConnectionLogList extends ConnectionLog { siteNm: string; menuNm: string; wbsrKndNm: string; } +export interface ConnectionLogPayload { + cntnId?: string; + cntnIp?: string; + cntnRgn?: string; + wbsrKnd?: string; + menuCd?: number; + siteId?: string; + urlPath: string; +} + export interface ConnectionStatisticsParams { keywordType?: string; keyword?: string; @@ -62,11 +75,14 @@ export interface ConnectionStatistics { browserList: BrowserConnectionStatistics[]; } -export type ConnectionLogList = PageableList; +export type ConnectionLogPageList = PageableList; export interface ConnectionLogService { - getConnectionLog(params: ConnectionLogParams): Promise; + getConnectionLogPage( + params: ConnectionLogParams, + ): Promise; getConnectionStatistics( params: ConnectionStatisticsParams, ): Promise; + saveConnectionLog(payload: ConnectionLogPayload): Promise; } diff --git a/apps/cs/src/pages/user-statistics/model/chart-data.ts b/apps/cs/src/pages/user-statistics/model/chart-data.ts index 455dcac56..87a5322c1 100644 --- a/apps/cs/src/pages/user-statistics/model/chart-data.ts +++ b/apps/cs/src/pages/user-statistics/model/chart-data.ts @@ -1,6 +1,6 @@ import type { ChartData, ChartOptions } from "chart.js"; import { getCssVariableValue } from "@common/components"; -import type { ConnectionStatistics } from "./connection-log-interface"; +import type { ConnectionStatistics } from "@/entities/connection-log"; export const chartData = { day: ( diff --git a/apps/cs/src/pages/user-statistics/model/table-columns.ts b/apps/cs/src/pages/user-statistics/model/table-columns.ts index 09fe58adf..8530345d3 100644 --- a/apps/cs/src/pages/user-statistics/model/table-columns.ts +++ b/apps/cs/src/pages/user-statistics/model/table-columns.ts @@ -1,5 +1,5 @@ import type { ColumnDef } from "@tanstack/react-table"; -import type { ConnectionLog } from "./connection-log-interface"; +import type { ConnectionLog } from "@/entities/connection-log"; import dayjs from "dayjs"; export const columns: ColumnDef[] = [ diff --git a/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx b/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx index 801ca5eb0..b4c821551 100644 --- a/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx +++ b/apps/cs/src/pages/user-statistics/ui/user-statistics-page.tsx @@ -27,15 +27,17 @@ import { SelectTrigger, SelectValue, } from "@common/components"; +import { + ConnectionLogApi, + type ConnectionStatisticsParams, +} from "@/entities/connection-log"; import { SiteSelect } from "@/entities/site"; import { useDataTable } from "@/shared/lib"; import { ENDPOINT } from "@/shared/config"; import { NoData } from "@/shared/ui/no-data"; import { InputDateRangePicker } from "@/shared/ui/input-date-range-picker"; -import { ConnectionLogApi } from "../api/connection-log-service"; import { chartData } from "../model/chart-data"; import { columns } from "../model/table-columns"; -import type { ConnectionStatisticsParams } from "../model/connection-log-interface"; ChartJS.register( CategoryScale, @@ -78,10 +80,12 @@ function UserStatisticsPage() { }); const query = useQuery({ - queryKey: [ENDPOINT.CMS_SERVICE.CONNECTION_LOG, searchParams], + queryKey: [ENDPOINT.CMS_SERVICE.CONNECTION_LOG, searchParams, pagination], queryFn: () => - ConnectionLogApi.getConnectionLog({ + ConnectionLogApi.getConnectionLogPage({ ...searchParams, + page: pagination.pageIndex, + size: pagination.pageSize, }), placeholderData: keepPreviousData, }); diff --git a/packages/common/components/src/api/connection-log.ts b/packages/common/components/src/api/connection-log.ts new file mode 100644 index 000000000..b421b7cb3 --- /dev/null +++ b/packages/common/components/src/api/connection-log.ts @@ -0,0 +1,34 @@ +import { ENDPOINT } from "../config"; +import { getApiClient } from "./client"; + +export interface ConnectionLog { + cntnSn: number; + cntnDt: string; + cntnId: string; + cntnIp: string; + cntnRgn: string; + wbsrKnd: string; + menuCd: number; + siteId: string; + urlPath: string; +} + +export interface ConnectionLogPayload { + cntnId?: string; + cntnIp?: string; + cntnRgn?: string; + wbsrKnd?: string; + menuCd?: number | null; + siteId?: string; + urlPath: string; +} + +const client = getApiClient(); + +export const saveConnectionLog = async (payload: ConnectionLogPayload) => { + const response = await client.post( + `${ENDPOINT.CMS_SERVICE.CONNECTION_LOG}`, + payload, + ); + return response.data; +}; diff --git a/packages/common/components/src/api/index.ts b/packages/common/components/src/api/index.ts index 10d68732c..d569765c2 100644 --- a/packages/common/components/src/api/index.ts +++ b/packages/common/components/src/api/index.ts @@ -1,4 +1,5 @@ export * from "./client"; +export * from "./connection-log"; export * from "./menu"; export * from "./popup"; export * from "./site"; diff --git a/packages/common/components/src/config/api.ts b/packages/common/components/src/config/api.ts index 6772182fb..a12ff5887 100644 --- a/packages/common/components/src/config/api.ts +++ b/packages/common/components/src/config/api.ts @@ -6,6 +6,7 @@ export const ENDPOINT = { SITES: "/cms-service/api/v1/sites", POPUPS: "/cms-service/api/v1/popups", IPS: "/cms-service/api/v1/site-ips", + CONNECTION_LOG: "/cms-service/api/v1/cntnlog", }, USER_SERVICE: { USERS: "/user-service/api/v1/users", diff --git a/packages/common/components/src/ui/lnb/index.tsx b/packages/common/components/src/ui/lnb/index.tsx index d7fabd39b..8e3c2aebf 100644 --- a/packages/common/components/src/ui/lnb/index.tsx +++ b/packages/common/components/src/ui/lnb/index.tsx @@ -3,6 +3,7 @@ import { useState, useEffect, useRef } from "react"; import { useQuery } from "@tanstack/react-query"; import { ChevronRight } from "lucide-react"; +import { useDetectDevice } from "@frontend-opensource/use-react-hooks"; import { getConfig } from "@common/config"; import { getParentIds } from "./lib"; import { @@ -24,9 +25,10 @@ import { import { ENDPOINT } from "../../config"; import { cn, getCookie, setCookie } from "../../lib"; import { - getAnonymouseMenuList, getMenuList, getPreviewTreeMenuList, + getAnonymouseMenuList, + saveConnectionLog, type MenuItem, } from "../../api"; @@ -55,6 +57,7 @@ export function LNB({ const [defaultOpenMenuIds, setDefaultOpenMenuIds] = useState([]); const [currentMenuCode, setCurrentMenuCode] = useState(null); const prevPathRef = useRef(currentPath); + const { browser } = useDetectDevice(); const siteId = propSiteId ?? appSiteId; @@ -67,7 +70,7 @@ export function LNB({ const { data: previewTreeMenuListData } = useQuery({ queryKey: [ENDPOINT.CMS_SERVICE.MENUS, siteId, "preview"], queryFn: () => getPreviewTreeMenuList(siteId), - enabled: isLoggedIn && previewMode, + enabled: isLoggedIn && !!previewMode, }); const { data: anonymousMenuListData } = useQuery({ @@ -125,6 +128,16 @@ export function LNB({ } if (matchedMenuCode) setCurrentMenuCode(matchedMenuCode); + + // 접속 로그 저장 + saveConnectionLog({ + cntnId: userId, + cntnRgn: navigator.language, + wbsrKnd: browser, + menuCd: matchedMenuCode, + siteId, + urlPath: currentPath, + }); }, [menuList, currentPath]); function MenuItem({