[cs] feat: 대시보드 페이지 일정 패널 작업

This commit is contained in:
2026-02-04 09:34:50 +09:00
parent 912e335b27
commit 7227b98961
3 changed files with 100 additions and 20 deletions
@@ -4,6 +4,8 @@ import type {
Dashboard,
DashboardService,
NoticeUser,
Schedule,
ScheduleQueryParams,
} from "../model/dashboard-interface";
import type { PageableList } from "@/shared/model";
@@ -23,6 +25,16 @@ export class DashboardApiService implements DashboardService {
);
return response.data;
}
public async getScheduleList(
params?: ScheduleQueryParams,
): Promise<Schedule[]> {
const response = await client.get<Schedule[]>(
ENDPOINT.CMS_SERVICE.SCHEDULES,
{ params },
);
return response.data;
}
}
export const DashboardApi = new DashboardApiService();
@@ -39,7 +39,32 @@ export interface NoticeUser {
regDt: string;
}
export interface Schedule {
schdlBgngDt: string;
schdlEndDt: string;
actualDate: string;
schdlSn: number;
siteId: string;
schdlTtl: string;
schdlSeCd: string;
schdlCn: string;
reptYn: string;
commSchdlYn: string;
atflCd: string | null;
}
export interface ScheduleQueryParams {
siteId?: string;
schdlTtl?: string;
schdlSeCd?: string;
schdlBgngYmd?: string;
schdlEndYmd?: string;
reptYn?: string;
commSchdlYn?: string;
}
export interface DashboardService {
getDashboard(): Promise<Dashboard>;
getNoticeUserList(recvUnqId: string): Promise<PageableList<NoticeUser>>;
getScheduleList(params?: ScheduleQueryParams): Promise<Schedule[]>;
}
@@ -18,7 +18,7 @@ import {
} from "chart.js";
import { Bar, Line } from "react-chartjs-2";
import { PostApi, type RecentPost } from "@/entities/post";
import { AUTH_USER_ID, ENDPOINT } from "@/shared/config";
import { AUTH_USER_ID, ENDPOINT, SITE_ID } from "@/shared/config";
import { getCookie, useDataTable } from "@/shared/lib";
import { DashboardApi } from "../api/dashboard-service";
import { chartData } from "../model/chart-data";
@@ -53,6 +53,29 @@ function DashboardPage() {
queryKey: [ENDPOINT.CMS_SERVICE.NOTICE_USER],
queryFn: () => DashboardApi.getNoticeUserList(userId),
enabled: !!userId,
select: (data) => {
// 오늘 ~ 한 달 전 사이의 일정
const today = dayjs().endOf("day");
const monthAgo = dayjs().subtract(1, "month").startOf("day");
return data.content?.filter((item) => {
const regDt = dayjs(item.regDt);
return (
(regDt.isSame(monthAgo) || regDt.isAfter(monthAgo)) &&
(regDt.isSame(today) || regDt.isBefore(today))
);
});
},
});
const { data: scheduleList } = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.SCHEDULES],
queryFn: () =>
DashboardApi.getScheduleList({
siteId: SITE_ID,
schdlBgngYmd: dayjs().format("YYYY-MM-DD"),
schdlEndYmd: dayjs().add(1, "month").format("YYYY-MM-DD"),
commSchdlYn: "Y",
}),
});
const noticePostQuery = useQuery({
@@ -333,7 +356,7 @@ function DashboardPage() {
</div>
<div className="p-4">
<div className="space-y-4 text-foreground">
{noticeUserList?.content?.map((item) => (
{noticeUserList?.map((item) => (
<div
key={item.notiId}
className="flex items-center justify-between border-b border-border pb-4"
@@ -352,24 +375,44 @@ 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">
{(3).toLocaleString()}월 정기 시스템 점검
</span>
<span>내일</span>
</div>
<div className="flex items-center justify-between border-b border-border pb-4">
<span className="font-medium">서버 업데이트 예정</span>
<span>{(3).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">
<span className="font-medium">정기 보안 점검</span>
<span>{(7).toLocaleString()}일 후</span>
</div>
{scheduleList && scheduleList.length > 0 ? (
scheduleList.map((schedule, index) => {
const today = dayjs();
const scheduleDate = dayjs(schedule.actualDate);
const daysUntil = scheduleDate.diff(today, "day");
let timeText = "";
if (daysUntil === 0) {
timeText = "오늘";
} else if (daysUntil === 1) {
timeText = "내일";
} else if (daysUntil > 1) {
timeText = `${daysUntil}일 후`;
} else {
timeText = scheduleDate.format("YYYY-MM-DD");
}
return (
<div
key={schedule.schdlSn}
className={`flex items-center justify-between ${
index < scheduleList.length - 1
? "border-b border-border pb-4"
: ""
}`}
>
<span className="font-medium">
{schedule.schdlTtl}
</span>
<span>{timeText}</span>
</div>
);
})
) : (
<div className="text-center text-muted-foreground">
예정된 일정이 없습니다.
</div>
)}
</div>
</div>
</div>