[cs] feat: 대시보드 페이지 실시간 알림 패널 작업

This commit is contained in:
2026-02-03 17:48:15 +09:00
parent 8a160dc97c
commit 912e335b27
5 changed files with 58 additions and 26 deletions
@@ -1,6 +1,11 @@
import { client } from "@/shared/api";
import { ENDPOINT } from "@/shared/config";
import type { Dashboard, DashboardService } from "../model/dashboard-interface";
import type {
Dashboard,
DashboardService,
NoticeUser,
} from "../model/dashboard-interface";
import type { PageableList } from "@/shared/model";
export class DashboardApiService implements DashboardService {
public async getDashboard(): Promise<Dashboard> {
@@ -9,6 +14,15 @@ export class DashboardApiService implements DashboardService {
);
return response.data;
}
public async getNoticeUserList(
recvUnqId: string,
): Promise<PageableList<NoticeUser>> {
const response = await client.get<PageableList<NoticeUser>>(
`${ENDPOINT.CMS_SERVICE.NOTICE_USER}/${recvUnqId}/list`,
);
return response.data;
}
}
export const DashboardApi = new DashboardApiService();
@@ -1,3 +1,5 @@
import type { PageableList } from "@/shared/model";
export interface SiteStatisticsContent {
siteId: string;
siteNm: string;
@@ -27,6 +29,17 @@ export interface Dashboard {
menuAccessList: MenuStatisticsContent[];
}
export interface NoticeUser {
notiId: number;
recvUnqId: string;
senderUnqId: string;
notiType: string;
notiTtl: string;
notReadYn: string;
regDt: string;
}
export interface DashboardService {
getDashboard(): Promise<Dashboard>;
getNoticeUserList(recvUnqId: string): Promise<PageableList<NoticeUser>>;
}
@@ -1,5 +1,6 @@
"use client";
import dayjs from "dayjs";
import { useRouter } from "next/navigation";
import { useQuery } from "@tanstack/react-query";
import { getCoreRowModel } from "@tanstack/react-table";
@@ -17,8 +18,8 @@ import {
} from "chart.js";
import { Bar, Line } from "react-chartjs-2";
import { PostApi, type RecentPost } from "@/entities/post";
import { ENDPOINT } from "@/shared/config";
import { useDataTable } from "@/shared/lib";
import { AUTH_USER_ID, ENDPOINT } from "@/shared/config";
import { getCookie, useDataTable } from "@/shared/lib";
import { DashboardApi } from "../api/dashboard-service";
import { chartData } from "../model/chart-data";
import {
@@ -39,12 +40,21 @@ ChartJS.register(
);
function DashboardPage() {
const userId = getCookie(AUTH_USER_ID) ?? "";
const router = useRouter();
const { data } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.DASHBOARD],
queryFn: () => DashboardApi.getDashboard(),
});
const { data: noticeUserList } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.NOTICE_USER],
queryFn: () => DashboardApi.getNoticeUserList(userId),
enabled: !!userId,
});
const noticePostQuery = useQuery({
queryKey: [ENDPOINT.BOARD_SERVICE.POSTS],
queryFn: () =>
@@ -323,22 +333,15 @@ function DashboardPage() {
</div>
<div className="p-4">
<div className="space-y-4 text-foreground">
<div className="flex items-center justify-between border-b border-border pb-4">
<span className="font-medium">신규 사용자 가입</span>
<span>{(1).toLocaleString()}분 전</span>
</div>
<div className="flex items-center justify-between border-b border-border pb-4">
<span className="font-medium">메뉴 수정 요청</span>
<span>{(5).toLocaleString()}분 전</span>
</div>
<div className="flex items-center justify-between border-b border-border pb-4">
<span className="font-medium">게시물 신고</span>
<span>{(10).toLocaleString()}분 전</span>
</div>
<div className="flex items-center justify-between">
<span className="font-medium">컨텐츠 승인 요청</span>
<span>{(15).toLocaleString()}분 전</span>
</div>
{noticeUserList?.content?.map((item) => (
<div
key={item.notiId}
className="flex items-center justify-between border-b border-border pb-4"
>
<span className="font-medium">{item.notiTtl}</span>
<span>{dayjs(item.regDt).fromNow()}</span>
</div>
))}
</div>
</div>
</div>
+1
View File
@@ -56,6 +56,7 @@ export const ENDPOINT = {
APILOG: "/cms-service/api/v1/api-logs",
SITE_AUTHORITY: "/cms-service/api/v1/site-authrt",
CONNECTION_LOG: "/cms-service/api/v1/cntnlog",
NOTICE_USER: "/cms-service/api/v1/noti/user",
},
BOARD_SERVICE: {
BBS: "/board-service/api/v1/bbs",
@@ -34,6 +34,7 @@ export function NoticePopover() {
queryKey: [ENDPOINT.CMS_SERVICE.NOTICE_USER],
queryFn: () => getNoticeUserList(userId!),
enabled: !!userId,
select: (data) => data.content.filter((item) => item.notReadYn === "N"),
});
const { data: unreadNoticeCount } = useQuery({
@@ -53,11 +54,11 @@ export function NoticePopover() {
};
const handleSelectAll = () => {
if (noticeUserList?.content) {
if (selectedNoticeIds.length === noticeUserList.content.length) {
if (noticeUserList) {
if (selectedNoticeIds.length === noticeUserList.length) {
setSelectedNoticeIds([]);
} else {
const allIds = noticeUserList.content.map((item) => item.notiId);
const allIds = noticeUserList.map((item) => item.notiId);
setSelectedNoticeIds(allIds);
}
}
@@ -79,9 +80,9 @@ export function NoticePopover() {
}
};
const isAllSelected = noticeUserList?.content
? selectedNoticeIds.length === noticeUserList.content.length &&
noticeUserList.content.length > 0
const isAllSelected = noticeUserList
? selectedNoticeIds.length === noticeUserList.length &&
noticeUserList.length > 0
: false;
useEffect(() => {
@@ -107,7 +108,7 @@ export function NoticePopover() {
</Label>
</div>
<ul>
{noticeUserList?.content?.map((item) => (
{noticeUserList?.map((item) => (
<li
key={item.notiId}
className={cn(