Merge pull request 'iipbs_cs' (#16) from iipbs_cs into main
Reviewed-on: #16
@@ -1,2 +0,0 @@
|
||||
import { BoardPage } from "@/pages/board";
|
||||
export default BoardPage;
|
||||
@@ -1 +0,0 @@
|
||||
export { AttachmentApi } from "./api/attachment-service";
|
||||
@@ -1,22 +0,0 @@
|
||||
export interface Attachment {
|
||||
atflCd: string;
|
||||
atflSn: number;
|
||||
atflId: string;
|
||||
physFileNm: string;
|
||||
orgnlFileNm: string;
|
||||
atflFlieSz: number;
|
||||
atflType: string;
|
||||
dwnldNocs: number;
|
||||
delYn: string;
|
||||
lnkgDmnId: string;
|
||||
lnkgDmnNm: string;
|
||||
regDt: string;
|
||||
}
|
||||
|
||||
export interface AttachmentService {
|
||||
getAttachments: (atflCd: string) => Promise<Attachment[]>;
|
||||
deleteAttachment: (atflId: string) => Promise<void>;
|
||||
deleteAttachmentByAtflCd: (atflCd: string) => Promise<void>;
|
||||
getImageUrl: (atflId: string) => Promise<string>;
|
||||
getImageUrlByAtflCd: (atflCd: string) => Promise<string>;
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
export { LoginApi } from "./api/login-service";
|
||||
export { AuthWrapper } from "./lib/auth-wrapper";
|
||||
@@ -1,49 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { client } from "@/shared/api";
|
||||
import type { IUserInfo } from "@/shared/store";
|
||||
import { getCookie, useUserStore } from "@/shared/lib";
|
||||
import { ENDPOINT, AUTH_USER_ID } from "@/shared/config";
|
||||
import { LoginApi } from "../api/login-service";
|
||||
|
||||
const AuthWrapper = ({ children }: { children: React.ReactNode }) => {
|
||||
const router = useRouter();
|
||||
const { userInfo, setUserInfo } = useUserStore((state) => state);
|
||||
|
||||
async function authCheck() {
|
||||
const userId = getCookie(AUTH_USER_ID);
|
||||
if (!userId) {
|
||||
throw new Error("Missing required authentication tokens");
|
||||
}
|
||||
|
||||
const response = await client.get<IUserInfo>(
|
||||
`${ENDPOINT.USER_SERVICE.USERS}/${userId}`,
|
||||
);
|
||||
if (!userInfo) setUserInfo(response.data);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
await authCheck();
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
|
||||
try {
|
||||
await LoginApi.silentRefresh();
|
||||
await authCheck();
|
||||
} catch (refreshError) {
|
||||
console.error("Token refresh failed:", refreshError);
|
||||
setUserInfo(null);
|
||||
router.push("/auth/login");
|
||||
}
|
||||
}
|
||||
})();
|
||||
}, []);
|
||||
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
export { AuthWrapper };
|
||||
@@ -1,21 +0,0 @@
|
||||
import { client } from "@/shared/api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import type {
|
||||
BoardPopupList,
|
||||
BoardPopupParams,
|
||||
BoardService,
|
||||
} from "../model/board-interface";
|
||||
|
||||
export class BoardApiService implements BoardService {
|
||||
public async getBoardPopupList(
|
||||
params: BoardPopupParams,
|
||||
): Promise<BoardPopupList> {
|
||||
const response = await client.get<BoardPopupList>(
|
||||
`${ENDPOINT.BOARD_SERVICE.BBS}`,
|
||||
{ params },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
export const BoardApi = new BoardApiService();
|
||||
@@ -1,2 +0,0 @@
|
||||
export { BoardApi } from "./api/board-service";
|
||||
export { type BoardPopup } from "./model/board-interface";
|
||||
@@ -1,42 +0,0 @@
|
||||
import type { PageableList, PageableParams } from "@/shared/model";
|
||||
|
||||
export const BOARD_TYPE = {
|
||||
BBSNORMAL: "BBSNORMAL",
|
||||
BBSFAQ: "BBSFAQ",
|
||||
BBSIMAGE: "BBSIMAGE",
|
||||
BBSMOVIE: "BBSMOVIE",
|
||||
} as const;
|
||||
|
||||
export type BoardType = (typeof BOARD_TYPE)[keyof typeof BOARD_TYPE];
|
||||
|
||||
export interface BoardPopupParams extends PageableParams {
|
||||
bbsNm?: string;
|
||||
}
|
||||
|
||||
export interface BoardPopup {
|
||||
bbsId: number;
|
||||
bbsTypeCd: BoardType;
|
||||
bbsTypeNm: string;
|
||||
bbsNm: string;
|
||||
bbsExpln: string;
|
||||
rfrncUseYn: string;
|
||||
atflUseYn: string;
|
||||
atflMaxCnt: number;
|
||||
atflMaxFileSz: number;
|
||||
ansUseYn: string;
|
||||
cmntUseYn: string;
|
||||
dgstfnEvlUseYn: string;
|
||||
smsUseYn: string;
|
||||
upndFixUseYn: string;
|
||||
pstgPrdUseYn: string;
|
||||
popupUseYn: string;
|
||||
delYn: string;
|
||||
regDt: string;
|
||||
pstCnt: number;
|
||||
}
|
||||
|
||||
export type BoardPopupList = PageableList<BoardPopup>;
|
||||
|
||||
export interface BoardService {
|
||||
getBoardPopupList: (params: BoardPopupParams) => Promise<BoardPopupList>;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export { CodeSelect } from "./ui/code-select";
|
||||
@@ -1 +0,0 @@
|
||||
export { MenuWrapper } from "./lib/menu-wrapper";
|
||||
@@ -1 +0,0 @@
|
||||
export { BoardPage } from "./ui/board-page";
|
||||
@@ -1,5 +0,0 @@
|
||||
function BoardPage() {
|
||||
return <div>게시판 관리</div>;
|
||||
}
|
||||
|
||||
export { BoardPage };
|
||||
@@ -1,22 +0,0 @@
|
||||
import { PageTitle } from "@common/components";
|
||||
import { useMenuStore } from "../lib/use-menu-store";
|
||||
|
||||
function PageLayout({ children }: { children: React.ReactNode }) {
|
||||
const { currentMenuInfo } = useMenuStore((state) => state);
|
||||
|
||||
const menuPaths = currentMenuInfo?.menuPath
|
||||
?.split(">")
|
||||
.map((path) => path.trim());
|
||||
|
||||
return (
|
||||
<div className="h-auto min-h-full bg-container pb-2">
|
||||
<PageTitle
|
||||
title={currentMenuInfo?.menuKornNm ?? ""}
|
||||
menuPaths={menuPaths ?? []}
|
||||
/>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export { PageLayout };
|
||||
@@ -2,10 +2,9 @@
|
||||
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import type { MenuItem } from "@common/components/api";
|
||||
import { BaseLayout } from "@common/components/ui";
|
||||
import { BaseLayout } from "@common/components";
|
||||
import type { MenuItem } from "@/entities/menu";
|
||||
import { useMenuStore } from "@/shared/lib";
|
||||
import { PageLayout } from "@/shared/ui/page-layout";
|
||||
|
||||
export default function WithBaseLayout({
|
||||
children,
|
||||
@@ -29,7 +28,7 @@ export default function WithBaseLayout({
|
||||
currentPath={pathname ?? ""}
|
||||
handleMenuClick={handleMenuClick}
|
||||
>
|
||||
<PageLayout>{children}</PageLayout>
|
||||
{children}
|
||||
</BaseLayout>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { NoticePost } from "@/pages/notice";
|
||||
|
||||
export default async function PstBbsNoticePostPage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ bbsId: string; pstNo: string }>;
|
||||
}) {
|
||||
const { bbsId, pstNo } = await params;
|
||||
return <NoticePost bbsId={bbsId} pstNo={pstNo} />;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import { NoticePage } from "@/pages/notice";
|
||||
|
||||
export default async function PstBbsNoticePage({
|
||||
params,
|
||||
}: {
|
||||
params: Promise<{ bbsId: string }>;
|
||||
}) {
|
||||
const { bbsId } = await params;
|
||||
return <NoticePage bbsId={bbsId} />;
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { CLAIM_NAME, AUTH_USER_ID } from "./src/shared/config";
|
||||
|
||||
const serverApiUrl = process.env.NEXT_PUBLIC_SERVER_API_URL;
|
||||
const serverApiUrl =
|
||||
process.env.NEXT_PUBLIC_SERVER_API_URL ?? "http://localhost:13000";
|
||||
|
||||
export function middleware(req: NextRequest) {
|
||||
const pathname = req.nextUrl.pathname;
|
||||
@@ -12,6 +13,7 @@ export function middleware(req: NextRequest) {
|
||||
const newUrl = `${serverApiUrl}${pathname.replace("/server", "")}${
|
||||
queryParams ? `?${queryParams}` : ""
|
||||
}`;
|
||||
console.log(`[Middleware] Rewriting from '/server' path to: ${newUrl}`);
|
||||
return NextResponse.rewrite(new URL(newUrl));
|
||||
}
|
||||
|
||||
@@ -24,6 +26,9 @@ export function middleware(req: NextRequest) {
|
||||
if (token) requestHeaders.set(CLAIM_NAME, token);
|
||||
if (userId) requestHeaders.set(AUTH_USER_ID, userId);
|
||||
|
||||
console.log(
|
||||
`[Middleware] Rewriting from '/attach-service' path to: ${newUrl}`,
|
||||
);
|
||||
return NextResponse.rewrite(new URL(newUrl), {
|
||||
headers: requestHeaders,
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "feature",
|
||||
"name": "features",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@@ -11,6 +11,8 @@
|
||||
"dependencies": {
|
||||
"@common/assets": "workspace:*",
|
||||
"@common/components": "workspace:*",
|
||||
"@common/config": "workspace:*",
|
||||
"@common/network": "workspace:*",
|
||||
"@frontend-opensource/use-react-hooks": "^1.1.4",
|
||||
"@hookform/resolvers": "^4.1.3",
|
||||
"@minoru/react-dnd-treeview": "^3.5.0",
|
||||
@@ -23,7 +25,7 @@
|
||||
"chart.js": "^4.4.8",
|
||||
"dayjs": "^1.11.13",
|
||||
"js-cookie": "^3.0.5",
|
||||
"next": "15.1.7",
|
||||
"next": "15.3.0",
|
||||
"react-chartjs-2": "^5.3.0",
|
||||
"react-dnd": "^16.0.1",
|
||||
"react-hook-form": "^7.54.2",
|
||||
|
Before Width: | Height: | Size: 132 KiB After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
@@ -2,23 +2,24 @@
|
||||
|
||||
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { ConfirmProvider } from "@frontend-opensource/use-react-hooks";
|
||||
import { AuthWrapper } from "@/entities/auth";
|
||||
import { MenuWrapper } from "@/entities/menu";
|
||||
import { StoreProvider } from "@/shared/providers";
|
||||
import { AlertDialog } from "@/shared/ui/alert-dialog";
|
||||
import { ConfirmDialog } from "@/shared/ui/confirm-dialog";
|
||||
import { initializeNextClientConfig } from "@common/config";
|
||||
|
||||
const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {
|
||||
const queryClient = new QueryClient();
|
||||
|
||||
initializeNextClientConfig();
|
||||
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<StoreProvider>
|
||||
<ConfirmProvider>
|
||||
<AuthWrapper>
|
||||
<MenuWrapper>{children}</MenuWrapper>
|
||||
<AlertDialog />
|
||||
<ConfirmDialog />
|
||||
</AuthWrapper>
|
||||
<MenuWrapper>{children}</MenuWrapper>
|
||||
<AlertDialog />
|
||||
<ConfirmDialog />
|
||||
</ConfirmProvider>
|
||||
</StoreProvider>
|
||||
</QueryClientProvider>
|
||||
@@ -1,5 +1,6 @@
|
||||
@import "@common/assets/styles/base.css";
|
||||
@import "@common/assets/styles/diveicon.css";
|
||||
@import "@common/components/index.css";
|
||||
|
||||
@tailwind base;
|
||||
@tailwind utilities;
|
||||
@@ -2,11 +2,23 @@ import { client } from "@/shared/api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import type {
|
||||
Attachment,
|
||||
AttachmentList,
|
||||
AttachmentParams,
|
||||
AttachmentService,
|
||||
} from "../model/attachment-interface";
|
||||
|
||||
export class AttachmentApiService implements AttachmentService {
|
||||
public async getAttachments(atflCd: string): Promise<Attachment[]> {
|
||||
public async getAttachmentsList(
|
||||
params: AttachmentParams,
|
||||
): Promise<AttachmentList> {
|
||||
const response = await client.get<AttachmentList>(
|
||||
`${ENDPOINT.ATTACH_SERVICE.ATTACHMENTS}`,
|
||||
{ params },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getAttachmentsInfo(atflCd: string): Promise<Attachment[]> {
|
||||
const response = await client.get<Attachment[]>(
|
||||
`${ENDPOINT.ATTACH_SERVICE.ATTACHMENTS}/${atflCd}`,
|
||||
);
|
||||
@@ -0,0 +1,5 @@
|
||||
export { AttachmentApi } from "./api/attachment-service";
|
||||
export type {
|
||||
AttachmentParams,
|
||||
Attachment,
|
||||
} from "./model/attachment-interface";
|
||||
@@ -0,0 +1,42 @@
|
||||
import type { PageableList, PageableParams } from "@/shared/model";
|
||||
|
||||
export interface AttachmentParams extends PageableParams {
|
||||
keywordType?: string;
|
||||
keyword?: string;
|
||||
atflCd?: string;
|
||||
atflSn?: number;
|
||||
atflId?: string;
|
||||
orgnlFileNm?: string;
|
||||
atflFlieSz?: number;
|
||||
atflType?: string;
|
||||
dwnldNocs?: number;
|
||||
delYn?: string;
|
||||
lnkgDmnId?: string;
|
||||
lnkgDmnNm?: string;
|
||||
}
|
||||
|
||||
export interface Attachment {
|
||||
atflCd: string;
|
||||
atflSn: number;
|
||||
atflId: string;
|
||||
physFileNm: string;
|
||||
orgnlFileNm: string;
|
||||
atflFlieSz: number;
|
||||
atflType: string;
|
||||
dwnldNocs: number;
|
||||
delYn: string;
|
||||
lnkgDmnId: string;
|
||||
lnkgDmnNm: string;
|
||||
regDt: string;
|
||||
}
|
||||
|
||||
export type AttachmentList = PageableList<Attachment>;
|
||||
|
||||
export interface AttachmentService {
|
||||
getAttachmentsList: (params: AttachmentParams) => Promise<AttachmentList>;
|
||||
getAttachmentsInfo: (atflCd: string) => Promise<Attachment[]>;
|
||||
deleteAttachment: (atflId: string) => Promise<void>;
|
||||
deleteAttachmentByAtflCd: (atflCd: string) => Promise<void>;
|
||||
getImageUrl: (atflId: string) => Promise<string>;
|
||||
getImageUrlByAtflCd: (atflCd: string) => Promise<string>;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export { LoginApi } from "./api/login-service";
|
||||
@@ -0,0 +1,60 @@
|
||||
import { client } from "@/shared/api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import type {
|
||||
Board,
|
||||
BoardFormData,
|
||||
BoardList,
|
||||
BoardParams,
|
||||
BoardPopupList,
|
||||
BoardPopupParams,
|
||||
BoardService,
|
||||
} from "../model/board-interface";
|
||||
|
||||
export class BoardApiService implements BoardService {
|
||||
public async getBoardList(params: BoardParams): Promise<BoardList> {
|
||||
const response = await client.get<BoardList>(
|
||||
`${ENDPOINT.BOARD_SERVICE.BBS}`,
|
||||
{ params },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getBoardPopupList(
|
||||
params: BoardPopupParams,
|
||||
): Promise<BoardPopupList> {
|
||||
const response = await client.get<BoardPopupList>(
|
||||
`${ENDPOINT.BOARD_SERVICE.BBS}`,
|
||||
{ params },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getBoardInfo(bbsId: string): Promise<Board> {
|
||||
const response = await client.get<Board>(
|
||||
`${ENDPOINT.BOARD_SERVICE.BBS}/${bbsId}`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async createBoard(data: BoardFormData): Promise<Board> {
|
||||
const response = await client.post<Board>(
|
||||
`${ENDPOINT.BOARD_SERVICE.BBS}`,
|
||||
data,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async updateBoard(bbsId: string, data: BoardFormData): Promise<Board> {
|
||||
const response = await client.put<Board>(
|
||||
`${ENDPOINT.BOARD_SERVICE.BBS}/${bbsId}`,
|
||||
data,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async deleteBoard(bbsId: string): Promise<void> {
|
||||
await client.delete(`${ENDPOINT.BOARD_SERVICE.BBS}/${bbsId}`);
|
||||
}
|
||||
}
|
||||
|
||||
export const BoardApi = new BoardApiService();
|
||||
@@ -0,0 +1,8 @@
|
||||
export { BoardApi } from "./api/board-service";
|
||||
export {
|
||||
boardFormSchema,
|
||||
type Board,
|
||||
type BoardFormData,
|
||||
type BoardParams,
|
||||
type BoardPopup,
|
||||
} from "./model/board-interface";
|
||||
@@ -0,0 +1,96 @@
|
||||
import { z } from "zod";
|
||||
import type { PageableList, PageableParams } from "@/shared/model";
|
||||
|
||||
export const BOARD_TYPE = {
|
||||
BBSNORMAL: "BBSNORMAL",
|
||||
BBSFAQ: "BBSFAQ",
|
||||
BBSIMAGE: "BBSIMAGE",
|
||||
BBSMOVIE: "BBSMOVIE",
|
||||
} as const;
|
||||
|
||||
export type BoardType = (typeof BOARD_TYPE)[keyof typeof BOARD_TYPE];
|
||||
|
||||
export interface BoardParams extends PageableParams {
|
||||
keywordType?: string;
|
||||
keyword?: string;
|
||||
bbsId?: number;
|
||||
bbsTypeCd?: string;
|
||||
bbsNm?: string;
|
||||
bbsExpln?: string;
|
||||
rfrncUseYn?: string;
|
||||
atflUseYn?: string;
|
||||
atflMaxCnt?: number;
|
||||
atflMaxFileSz?: number;
|
||||
ansUseYn?: string;
|
||||
cmntUseYn?: string;
|
||||
dgstfnEvlUseYn?: string;
|
||||
smsUseYn?: string;
|
||||
upndFixUseYn?: string;
|
||||
pstgPrdUseYn?: string;
|
||||
popupUseYn?: string;
|
||||
delYn?: string;
|
||||
}
|
||||
|
||||
export interface BoardPopupParams extends PageableParams {
|
||||
bbsNm?: string;
|
||||
}
|
||||
|
||||
export interface Board {
|
||||
bbsId: number;
|
||||
bbsTypeCd: string;
|
||||
bbsTypeNm: string;
|
||||
bbsNm: string;
|
||||
bbsExpln: string;
|
||||
rfrncUseYn: string;
|
||||
atflUseYn: string;
|
||||
atflMaxCnt: number;
|
||||
atflMaxFileSz: number;
|
||||
ansUseYn: string;
|
||||
ansUseAuthrt: string;
|
||||
cmntUseYn: string;
|
||||
dgstfnEvlUseYn: string;
|
||||
smsUseYn: string;
|
||||
upndFixUseYn: string;
|
||||
pstgPrdUseYn: string;
|
||||
popupUseYn: string;
|
||||
delYn: string;
|
||||
useYn: string;
|
||||
mdfcnDt: string;
|
||||
mdfrNm: string;
|
||||
}
|
||||
|
||||
export interface BoardPopup extends Board {
|
||||
pstCnt: number;
|
||||
}
|
||||
|
||||
export const boardFormSchema = z.object({
|
||||
bbsTypeCd: z.string(),
|
||||
bbsNm: z.string(),
|
||||
bbsExpln: z.string(),
|
||||
rfrncUseYn: z.string(),
|
||||
atflUseYn: z.string(),
|
||||
atflMaxCnt: z.number().nullish(),
|
||||
atflMaxFileSz: z.number().nullish(),
|
||||
ansUseYn: z.string(),
|
||||
ansUseAuthrt: z.string().nullish(),
|
||||
cmntUseYn: z.string(),
|
||||
dgstfnEvlUseYn: z.string(),
|
||||
smsUseYn: z.string(),
|
||||
upndFixUseYn: z.string(),
|
||||
pstgPrdUseYn: z.string(),
|
||||
popupUseYn: z.string(),
|
||||
useYn: z.string(),
|
||||
});
|
||||
|
||||
export type BoardList = PageableList<Board>;
|
||||
export type BoardPopupList = PageableList<BoardPopup>;
|
||||
export type BoardFormData = z.infer<typeof boardFormSchema>;
|
||||
|
||||
export interface BoardService {
|
||||
getBoardList: (params: BoardParams) => Promise<BoardList>;
|
||||
getBoardPopupList: (params: BoardPopupParams) => Promise<BoardPopupList>;
|
||||
getBoardInfo: (bbsId: string) => Promise<Board>;
|
||||
createBoard: (data: BoardFormData) => Promise<Board>;
|
||||
updateBoard: (bbsId: string, data: BoardFormData) => Promise<Board>;
|
||||
deleteBoard: (bbsId: string) => Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export { CodeApi } from "./api/code-service";
|
||||
export type { ICode } from "./model/code-interface";
|
||||
export { CodeSelect } from "./ui/code-select";
|
||||
@@ -2,6 +2,7 @@ export interface ICode {
|
||||
lwpoCd: string;
|
||||
upCd: string;
|
||||
lwpoCdNm: string;
|
||||
unit: string;
|
||||
}
|
||||
|
||||
export interface CodeService {
|
||||
@@ -0,0 +1,90 @@
|
||||
import { client } from "@/shared/api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import type {
|
||||
ContentsService,
|
||||
ContentsParams,
|
||||
ContentsList,
|
||||
ContentsFormData,
|
||||
ContentsVersionParams,
|
||||
ContentsVersionList,
|
||||
ContentsDetail,
|
||||
} from "../model/contents-interface";
|
||||
|
||||
export class ContentsApiService implements ContentsService {
|
||||
public async getContentsList(params: ContentsParams): Promise<ContentsList> {
|
||||
const response = await client.get<ContentsList>(
|
||||
`${ENDPOINT.CMS_SERVICE.CONTENTS}`,
|
||||
{ params },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getContentsVersionList(
|
||||
params: ContentsVersionParams,
|
||||
): Promise<ContentsVersionList> {
|
||||
const response = await client.get<ContentsVersionList>(
|
||||
`${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}`,
|
||||
{ params },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getLatestContentsInfo(
|
||||
contsSn: number,
|
||||
contsVer: number,
|
||||
): Promise<ContentsDetail> {
|
||||
const response = await client.get<ContentsDetail>(
|
||||
`${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}/${contsSn}/${contsVer}`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async createContents(data: ContentsFormData): Promise<void> {
|
||||
const response = await client.post<void>(
|
||||
`${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}`,
|
||||
data,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async updateContents(
|
||||
contsSn: number,
|
||||
contsVer: number,
|
||||
data: ContentsFormData,
|
||||
): Promise<void> {
|
||||
const response = await client.put<void>(
|
||||
`${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}/${contsSn}/${contsVer}`,
|
||||
data,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async deleteContents(
|
||||
contsSn: number,
|
||||
contsVer: number,
|
||||
): Promise<void> {
|
||||
await client.delete(
|
||||
`${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}/${contsSn}/${contsVer}`,
|
||||
);
|
||||
}
|
||||
|
||||
public async requestApprove(
|
||||
contsSn: number,
|
||||
contsVer: number,
|
||||
): Promise<void> {
|
||||
await client.put(
|
||||
`${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}/${contsSn}/${contsVer}/approveRequest`,
|
||||
);
|
||||
}
|
||||
|
||||
public async approveContents(
|
||||
contsSn: number,
|
||||
contsVer: number,
|
||||
): Promise<void> {
|
||||
await client.put(
|
||||
`${ENDPOINT.CMS_SERVICE.CONTENTS_DETAILS}/${contsSn}/${contsVer}/approve`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const ContentsApi = new ContentsApiService();
|
||||
@@ -0,0 +1,8 @@
|
||||
export { ContentsApi } from "./api/contents-service";
|
||||
export {
|
||||
CONTENTS_APPROVE_STATUS,
|
||||
contentsFormSchema,
|
||||
type Contents,
|
||||
type ContentsParams,
|
||||
type ContentsFormData,
|
||||
} from "./model/contents-interface";
|
||||
@@ -0,0 +1,100 @@
|
||||
import { z } from "zod";
|
||||
import type { PageableList, PageableParams } from "@/shared/model";
|
||||
|
||||
export const CONTENTS_APPROVE_STATUS = {
|
||||
DRAFT: "01",
|
||||
REQUESTED: "02",
|
||||
APPROVED: "99",
|
||||
} as const;
|
||||
|
||||
export type ContentsApproveStatus =
|
||||
(typeof CONTENTS_APPROVE_STATUS)[keyof typeof CONTENTS_APPROVE_STATUS];
|
||||
|
||||
export interface ContentsParams extends PageableParams {
|
||||
contsTtl?: string;
|
||||
aprvContsVer?: number;
|
||||
useYn?: string;
|
||||
}
|
||||
|
||||
export interface ContentsVersionParams extends PageableParams {
|
||||
contsSn?: number;
|
||||
contsCn?: string;
|
||||
aprvCd?: ContentsApproveStatus;
|
||||
cclCd?: string;
|
||||
koglCd?: string;
|
||||
tag?: string;
|
||||
useYn?: string;
|
||||
}
|
||||
|
||||
export interface ContentsVersion {
|
||||
contsSn: number;
|
||||
contsVer: number;
|
||||
contsCn: string;
|
||||
useYn: string;
|
||||
}
|
||||
|
||||
export const contentsSchema = z.object({
|
||||
contsSn: z.number(),
|
||||
contsTtl: z.string(),
|
||||
aprvContsVer: z.number(),
|
||||
useYn: z.string(),
|
||||
mdfcnDt: z.string(),
|
||||
mdfr: z.string(),
|
||||
mdfrNm: z.string(),
|
||||
aprvDt: z.string(),
|
||||
autzrNm: z.string(),
|
||||
workAprvCd: z.string(),
|
||||
workAprvNm: z.string(),
|
||||
workContsVer: z.number(),
|
||||
});
|
||||
|
||||
export const contentsDetailSchema = z.object({
|
||||
contsSn: z.number(),
|
||||
contsVer: z.number(),
|
||||
contsTtl: z.string(),
|
||||
contsCn: z.string(),
|
||||
contsRmrk: z.string().nullish(),
|
||||
aprvCd: z.enum([
|
||||
CONTENTS_APPROVE_STATUS.DRAFT,
|
||||
CONTENTS_APPROVE_STATUS.REQUESTED,
|
||||
CONTENTS_APPROVE_STATUS.APPROVED,
|
||||
]),
|
||||
cclCd: z.string().nullish(),
|
||||
koglCd: z.string().nullish(),
|
||||
tag: z.string().nullish(),
|
||||
aprvDt: z.string(),
|
||||
autzr: z.string(),
|
||||
useYn: z.string(),
|
||||
});
|
||||
|
||||
export const contentsFormSchema = contentsDetailSchema.omit({
|
||||
contsVer: true,
|
||||
aprvDt: true,
|
||||
autzr: true,
|
||||
});
|
||||
|
||||
export type Contents = z.infer<typeof contentsSchema>;
|
||||
export type ContentsDetail = z.infer<typeof contentsDetailSchema>;
|
||||
export type ContentsFormData = z.infer<typeof contentsFormSchema>;
|
||||
export type ContentsList = PageableList<Contents>;
|
||||
export type ContentsVersionList = PageableList<ContentsVersion>;
|
||||
|
||||
export interface ContentsService {
|
||||
getContentsList(params: ContentsParams): Promise<ContentsList>;
|
||||
getContentsVersionList(
|
||||
params: ContentsVersionParams,
|
||||
): Promise<ContentsVersionList>;
|
||||
getLatestContentsInfo(
|
||||
contsSn: number,
|
||||
contsVer: number,
|
||||
): Promise<ContentsDetail>;
|
||||
createContents(data: ContentsFormData): Promise<void>;
|
||||
updateContents(
|
||||
contsSn: number,
|
||||
contsVer: number,
|
||||
data: ContentsFormData,
|
||||
): Promise<void>;
|
||||
deleteContents(contsSn: number, contsVer: number): Promise<void>;
|
||||
requestApprove(contsSn: number, contsVer: number): Promise<void>;
|
||||
approveContents(contsSn: number, contsVer: number): Promise<void>;
|
||||
}
|
||||
@@ -49,6 +49,7 @@ const Editor = ({ ...props }: IAllProps) => {
|
||||
}}
|
||||
init={{
|
||||
...baseConfig.init,
|
||||
disabled: props.disabled,
|
||||
images_upload_handler: imagesUploadHandler,
|
||||
file_picker_callback: filePickerCallback,
|
||||
}}
|
||||
@@ -3,7 +3,7 @@ import { ENDPOINT } from "@/shared/config";
|
||||
import type {
|
||||
MenuAuthorityList,
|
||||
MenuAuthorityParams,
|
||||
MenuAuthorityPayloadData,
|
||||
MenuAuthorityPayload,
|
||||
MenuAuthorityService,
|
||||
} from "../model/menu-authority-interface";
|
||||
|
||||
@@ -18,9 +18,7 @@ export class MenuAuthorityApiService implements MenuAuthorityService {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async saveMenuAuthority(
|
||||
data: MenuAuthorityPayloadData[],
|
||||
): Promise<void> {
|
||||
public async saveMenuAuthority(data: MenuAuthorityPayload[]): Promise<void> {
|
||||
const response = await client.post<void>(
|
||||
`${ENDPOINT.CMS_SERVICE.MENU_AUTHRTS}`,
|
||||
data,
|
||||
@@ -30,12 +30,10 @@ export const menuAuthorityFormSchema = z.object({
|
||||
|
||||
export type MenuAuthority = z.infer<typeof menuAuthoritySchema>;
|
||||
export type MenuAuthorityList = PageableList<MenuAuthority>;
|
||||
export type MenuAuthorityPayloadData = z.infer<
|
||||
typeof menuAuthorityPayloadSchema
|
||||
>;
|
||||
export type MenuAuthorityPayload = z.infer<typeof menuAuthorityPayloadSchema>;
|
||||
export type MenuAuthorityFormData = z.infer<typeof menuAuthorityFormSchema>;
|
||||
|
||||
export interface MenuAuthorityService {
|
||||
getMenuAuthorityList(params: MenuAuthorityParams): Promise<MenuAuthorityList>;
|
||||
saveMenuAuthority(data: MenuAuthorityPayloadData[]): Promise<void>;
|
||||
saveMenuAuthority(data: MenuAuthorityPayload[]): Promise<void>;
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { ColumnDef } from "@tanstack/react-table";
|
||||
import type { UseFormReturn } from "react-hook-form";
|
||||
import { Checkbox } from "@common/components/ui";
|
||||
import { Checkbox } from "@common/components";
|
||||
import type {
|
||||
MenuAuthority,
|
||||
MenuAuthorityFormData,
|
||||
MenuAuthorityPayloadData,
|
||||
MenuAuthorityPayload,
|
||||
} from "./menu-authority-interface";
|
||||
|
||||
export const createColumns = (
|
||||
@@ -13,7 +13,7 @@ export const createColumns = (
|
||||
const getCurrentRow = (i: number) => form.watch("menuAuthority")[i];
|
||||
|
||||
const handleCheckedChange =
|
||||
(i: number, key: keyof MenuAuthorityPayloadData) => (checked: boolean) => {
|
||||
(i: number, key: keyof MenuAuthorityPayload) => (checked: boolean) => {
|
||||
if (getCurrentRow(i)?.mode === "R") {
|
||||
form.setValue(`menuAuthority.${i}.mode`, "U");
|
||||
}
|
||||
@@ -13,13 +13,13 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@common/components/ui";
|
||||
} from "@common/components";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { useAlertStore } from "@/shared/lib/use-alert-store";
|
||||
import {
|
||||
menuAuthorityFormSchema,
|
||||
type MenuAuthorityFormData,
|
||||
type MenuAuthorityPayloadData,
|
||||
type MenuAuthorityPayload,
|
||||
} from "../model/menu-authority-interface";
|
||||
import { createColumns } from "../model/menu-authority-table-columns";
|
||||
import { MenuAuthorityApi } from "../api/menu-authority-service";
|
||||
@@ -42,7 +42,7 @@ function ManagementAuthorityDialog({
|
||||
});
|
||||
|
||||
const { mutateAsync: saveMenuAuthority } = useMutation({
|
||||
mutationFn: (data: MenuAuthorityPayloadData[]) =>
|
||||
mutationFn: (data: MenuAuthorityPayload[]) =>
|
||||
MenuAuthorityApi.saveMenuAuthority(data),
|
||||
onSuccess: () => {
|
||||
alert("저장되었습니다.");
|
||||
@@ -1,4 +1,4 @@
|
||||
import { client } from "@common/components/api";
|
||||
import { client } from "@/shared/api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import type { MenuItem, MenuService } from "../model/menu-interface";
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { MenuWrapper } from "./lib/menu-wrapper";
|
||||
export type { MenuItem } from "./model/menu-interface";
|
||||
@@ -0,0 +1,66 @@
|
||||
import { client } from "@/shared/api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import {
|
||||
type Organization,
|
||||
type OrganizationFormData,
|
||||
type OrganizationService,
|
||||
type OrganizationTree,
|
||||
type OrganizationTreeForDnd,
|
||||
} from "../model/organization-interface";
|
||||
|
||||
export class OrganizationApiService implements OrganizationService {
|
||||
public async getOrganizationsTreeList(): Promise<OrganizationTree[]> {
|
||||
const response = await client.get<OrganizationTree[]>(
|
||||
`${ENDPOINT.CMS_SERVICE.ORGANIZATIONS}/tree`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getOrganizationInfo(ognzSn: number): Promise<Organization> {
|
||||
const response = await client.get<Organization>(
|
||||
`${ENDPOINT.CMS_SERVICE.ORGANIZATIONS}/${ognzSn}`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async createOrganization(data: OrganizationFormData): Promise<void> {
|
||||
await client.post<void>(`${ENDPOINT.CMS_SERVICE.ORGANIZATIONS}`, data);
|
||||
}
|
||||
|
||||
public async deleteOrganization(ognzSn: number): Promise<void> {
|
||||
await client.delete<void>(
|
||||
`${ENDPOINT.CMS_SERVICE.ORGANIZATIONS}/${ognzSn}`,
|
||||
);
|
||||
}
|
||||
|
||||
public async updateOrganizationName(
|
||||
ognzSn: number,
|
||||
name: string,
|
||||
): Promise<Organization> {
|
||||
const response = await client.put<Organization>(
|
||||
`${ENDPOINT.CMS_SERVICE.ORGANIZATIONS}/${ognzSn}/${name}`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async updateOrganization(
|
||||
ognzSn: number,
|
||||
data: OrganizationFormData,
|
||||
): Promise<void> {
|
||||
await client.put<void>(
|
||||
`${ENDPOINT.CMS_SERVICE.ORGANIZATIONS}/${ognzSn}`,
|
||||
data,
|
||||
);
|
||||
}
|
||||
|
||||
public async updateOrganizationByDnd(
|
||||
data: OrganizationTreeForDnd[],
|
||||
): Promise<void> {
|
||||
await client.put<void>(
|
||||
`${ENDPOINT.CMS_SERVICE.ORGANIZATIONS}/dnd/tree`,
|
||||
data,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const OrganizationApi = new OrganizationApiService();
|
||||
@@ -0,0 +1,8 @@
|
||||
export { OrganizationApi } from "./api/organization-service";
|
||||
export {
|
||||
organizationFormSchema,
|
||||
type OrganizationTree,
|
||||
type OrganizationFormData,
|
||||
type OrganizationTreeForDnd,
|
||||
} from "./model/organization-interface";
|
||||
export { generateOrganizationTreeData, handleDropNode } from "./lib/utils";
|
||||
@@ -0,0 +1,78 @@
|
||||
import type { DropOptions, NodeModel } from "@minoru/react-dnd-treeview";
|
||||
import type {
|
||||
OrganizationTree,
|
||||
OrganizationTreeForDnd,
|
||||
} from "../model/organization-interface";
|
||||
|
||||
export const generateOrganizationTreeData = (
|
||||
data: OrganizationTree[],
|
||||
): NodeModel<OrganizationTree>[] => {
|
||||
return data.reduce<NodeModel<OrganizationTree>[]>((acc, menu) => {
|
||||
const node: NodeModel<OrganizationTree> = {
|
||||
id: menu.ognzSn ?? 0,
|
||||
parent: menu.upOgnzSn ?? 0,
|
||||
text: menu.ognzNm,
|
||||
droppable: true,
|
||||
data: menu,
|
||||
};
|
||||
acc.push(node);
|
||||
|
||||
if (menu.children?.length) {
|
||||
acc.push(...generateOrganizationTreeData(menu.children));
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, []);
|
||||
};
|
||||
|
||||
export const generateDndOrganizationTreeData = (
|
||||
treeData: NodeModel<OrganizationTree>[],
|
||||
options: DropOptions<OrganizationTree>,
|
||||
): OrganizationTreeForDnd | null => {
|
||||
const { dragSourceId, dragSource, dropTargetId } = options;
|
||||
if (!dragSource?.data) return null;
|
||||
|
||||
const siblings = treeData.filter((node) => node.parent === dropTargetId);
|
||||
const dragSourceIndex = siblings.findIndex(
|
||||
(node) => node.id === dragSourceId,
|
||||
);
|
||||
const prevSibling = siblings[dragSourceIndex - 1];
|
||||
const newSortSeq =
|
||||
dragSourceIndex === 0 ? 1 : (prevSibling?.data?.sortSeq ?? 0) + 1;
|
||||
|
||||
const treeNode: OrganizationTreeForDnd = {
|
||||
ognzSn: dragSource.data.ognzSn,
|
||||
ognzNm: dragSource.data.ognzNm,
|
||||
ognzExpln: dragSource.data.ognzExpln,
|
||||
upOgnzSn: dropTargetId === 0 ? null : (dropTargetId as number),
|
||||
sortSeq: newSortSeq,
|
||||
};
|
||||
|
||||
const childNodes = treeData.filter(
|
||||
(node) => node.parent === dragSourceId && node.data,
|
||||
);
|
||||
const result: OrganizationTreeForDnd = {
|
||||
...treeNode,
|
||||
children:
|
||||
childNodes?.map((child) => ({
|
||||
ognzSn: child.data?.ognzSn,
|
||||
ognzNm: child.data?.ognzNm ?? "",
|
||||
ognzExpln: child.data?.ognzExpln,
|
||||
upOgnzSn: child.data?.upOgnzSn === 0 ? null : (dragSourceId as number),
|
||||
sortSeq: child.data?.sortSeq ?? 1,
|
||||
})) ?? [],
|
||||
};
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
export const handleDropNode =
|
||||
(callback: (newTree: OrganizationTreeForDnd) => void) =>
|
||||
(
|
||||
newTree: NodeModel<OrganizationTree>[],
|
||||
options: DropOptions<OrganizationTree>,
|
||||
) => {
|
||||
const newTreeData = generateDndOrganizationTreeData(newTree, options);
|
||||
if (!newTreeData) return;
|
||||
callback(newTreeData);
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
import { z } from "zod";
|
||||
|
||||
export const organizationSchema = z.object({
|
||||
ognzSn: z.number().nullish(),
|
||||
ognzNm: z.string(),
|
||||
ognzExpln: z.string().nullish(),
|
||||
upOgnzSn: z.number().nullish(),
|
||||
sortSeq: z.number(),
|
||||
useYn: z.string().nullish(),
|
||||
});
|
||||
|
||||
export const organizationFormSchema = organizationSchema.omit({
|
||||
ognzSn: true,
|
||||
});
|
||||
|
||||
export type Organization = z.infer<typeof organizationSchema>;
|
||||
export type OrganizationFormData = z.infer<typeof organizationFormSchema>;
|
||||
export type OrganizationTree = Organization & {
|
||||
children?: OrganizationTree[];
|
||||
};
|
||||
export type OrganizationTreeForDnd = Omit<OrganizationTree, "useYn">;
|
||||
|
||||
export interface OrganizationService {
|
||||
getOrganizationsTreeList(): Promise<OrganizationTree[]>;
|
||||
getOrganizationInfo(ognzSn: number): Promise<Organization>;
|
||||
createOrganization(data: OrganizationFormData): Promise<void>;
|
||||
deleteOrganization(ognzSn: number): Promise<void>;
|
||||
updateOrganizationName(ognzSn: number, name: string): Promise<Organization>;
|
||||
updateOrganization(ognzSn: number, data: OrganizationFormData): Promise<void>;
|
||||
updateOrganizationByDnd(data: OrganizationTreeForDnd[]): Promise<void>;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { client } from "@/shared/api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import type {
|
||||
PostInfo,
|
||||
PostList,
|
||||
PostParams,
|
||||
PostService,
|
||||
} from "../model/post-interface";
|
||||
|
||||
export class PostApiService implements PostService {
|
||||
public async getPostList(params: PostParams): Promise<PostList> {
|
||||
const response = await client.get<PostList>(ENDPOINT.BOARD_SERVICE.POSTS, {
|
||||
params,
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getPostInfo(bbsId: string, pstNo: string): Promise<PostInfo> {
|
||||
const response = await client.get<PostInfo>(
|
||||
`${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async deletePost(bbsId: string, pstNo: string): Promise<void> {
|
||||
await client.delete(`${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`);
|
||||
}
|
||||
}
|
||||
|
||||
export const PostApi = new PostApiService();
|
||||
@@ -0,0 +1,7 @@
|
||||
export { PostApi } from "./api/post-service";
|
||||
export type {
|
||||
Post,
|
||||
PostList,
|
||||
PostParams,
|
||||
PostService,
|
||||
} from "./model/post-interface";
|
||||
@@ -0,0 +1,47 @@
|
||||
import {
|
||||
type PageableList,
|
||||
type PageableParams,
|
||||
} from "@/shared/model/api-interface";
|
||||
|
||||
export interface PostParams extends PageableParams {
|
||||
keywordType?: string;
|
||||
keyword?: string;
|
||||
bbsId?: number;
|
||||
delYn?: string;
|
||||
frDateYmd?: string;
|
||||
toDateYmd?: string;
|
||||
}
|
||||
|
||||
export interface Post {
|
||||
bbsId: number;
|
||||
pstNo: number;
|
||||
pstTtl: string;
|
||||
inqNocs: number;
|
||||
rfrncUrl: string;
|
||||
popupYn: string;
|
||||
upndFixYn: string;
|
||||
prdPstgYn: string;
|
||||
rootPath: string;
|
||||
pstPath: string;
|
||||
ansPstn: number;
|
||||
wrtrNm: string;
|
||||
wrtrCplc: string;
|
||||
atflCd: string;
|
||||
regDt: string;
|
||||
rgtrNm: string;
|
||||
}
|
||||
|
||||
export interface PostInfo extends Post {
|
||||
pstCn: string;
|
||||
rgtr: string;
|
||||
mdfcnDt: string;
|
||||
mdfr: string;
|
||||
}
|
||||
|
||||
export type PostList = PageableList<Post>;
|
||||
|
||||
export interface PostService {
|
||||
getPostList(params: PostParams): Promise<PostList>;
|
||||
getPostInfo(bbsId: string, pstNo: string): Promise<PostInfo>;
|
||||
deletePost(bbsId: string, pstNo: string): Promise<void>;
|
||||
}
|
||||
@@ -5,7 +5,7 @@ import type {
|
||||
PostService,
|
||||
PostingParams,
|
||||
Post,
|
||||
PostPayloadData,
|
||||
PostPayload,
|
||||
} from "../model/posting-interface";
|
||||
|
||||
export class PostingApiService implements PostService {
|
||||
@@ -19,7 +19,7 @@ export class PostingApiService implements PostService {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async savePosting(data: PostPayloadData[]): Promise<Post[]> {
|
||||
public async savePosting(data: PostPayload[]): Promise<Post[]> {
|
||||
const response = await client.post<Post[]>(
|
||||
`${ENDPOINT.CMS_SERVICE.POSTINGS}`,
|
||||
data,
|
||||
@@ -2,6 +2,6 @@ export { PostingApi } from "./api/posting-service";
|
||||
export {
|
||||
POSTING_TYPE,
|
||||
type Post,
|
||||
type PostPayloadData,
|
||||
type PostPayload,
|
||||
} from "./model/posting-interface";
|
||||
export { PostingDialog } from "./ui/posting-dialog";
|
||||
@@ -41,10 +41,10 @@ export const postingFormSchema = z.object({
|
||||
});
|
||||
|
||||
export type Post = z.infer<typeof postSchema>;
|
||||
export type PostPayloadData = z.infer<typeof postPayloadSchema>;
|
||||
export type PostPayload = z.infer<typeof postPayloadSchema>;
|
||||
export type PostingFormData = z.infer<typeof postingFormSchema>;
|
||||
|
||||
export interface PostService {
|
||||
getPostingHistory: (params: PostingParams) => Promise<PageableList<Post>>;
|
||||
savePosting: (data: PostPayloadData[]) => Promise<Post[]>;
|
||||
savePosting: (data: PostPayload[]) => Promise<Post[]>;
|
||||
}
|
||||
@@ -23,8 +23,8 @@ import {
|
||||
DateRangePicker,
|
||||
DialogClose,
|
||||
DialogFooter,
|
||||
} from "@common/components/ui";
|
||||
import { cn } from "@common/components/lib";
|
||||
cn,
|
||||
} from "@common/components";
|
||||
import { CodeSelect } from "@/entities/code/@x/posting";
|
||||
import { SiteApi, type Site } from "@/entities/site/@x/posting";
|
||||
import type { PageableList } from "@/shared/model";
|
||||
@@ -34,7 +34,7 @@ import {
|
||||
postingFormSchema,
|
||||
type PostingFormData,
|
||||
type PostingType,
|
||||
type PostPayloadData,
|
||||
type PostPayload,
|
||||
} from "../model/posting-interface";
|
||||
import { useAlertStore } from "@/shared/lib/use-alert-store";
|
||||
|
||||
@@ -76,7 +76,7 @@ function PostingDialog({ postingType, postingTargets }: PostingDialogProps) {
|
||||
});
|
||||
|
||||
const { mutateAsync: savePosting } = useMutation({
|
||||
mutationFn: (data: PostPayloadData[]) => PostingApi.savePosting(data),
|
||||
mutationFn: (data: PostPayload[]) => PostingApi.savePosting(data),
|
||||
onSuccess: () => {
|
||||
alert("저장되었습니다.");
|
||||
},
|
||||
@@ -0,0 +1,62 @@
|
||||
import { client } from "@/shared/api";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import type {
|
||||
TreeUserOrganization,
|
||||
UserOrganizationParams,
|
||||
UserOrganizationList,
|
||||
UserOrganizationService,
|
||||
UserOrganizationPayload,
|
||||
SearchUserParams,
|
||||
SearchUserList,
|
||||
User,
|
||||
MoveUserOrganizationPayload,
|
||||
} from "../model/user-organization-interface";
|
||||
|
||||
export class UserOrganizationApiService implements UserOrganizationService {
|
||||
public async getUserOrganizationList(
|
||||
params: UserOrganizationParams,
|
||||
): Promise<UserOrganizationList> {
|
||||
const response = await client.get<UserOrganizationList>(
|
||||
`${ENDPOINT.CMS_SERVICE.USER_ORGANIZATION}`,
|
||||
{ params },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async getUserOrganizationTreeList(): Promise<TreeUserOrganization[]> {
|
||||
const response = await client.get<TreeUserOrganization[]>(
|
||||
`${ENDPOINT.CMS_SERVICE.USER_ORGANIZATION}/treeuser`,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async searchUser(params: SearchUserParams): Promise<SearchUserList> {
|
||||
const response = await client.get<SearchUserList>(
|
||||
`${ENDPOINT.CMS_SERVICE.USER_ORGANIZATION}/user-popup`,
|
||||
{ params },
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async saveUserOrganization(
|
||||
data: UserOrganizationPayload[],
|
||||
): Promise<User[]> {
|
||||
const response = await client.post<User[]>(
|
||||
`${ENDPOINT.CMS_SERVICE.USER_ORGANIZATION}`,
|
||||
data,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async moveUserOrganization(
|
||||
data: MoveUserOrganizationPayload[],
|
||||
): Promise<User[]> {
|
||||
const response = await client.post<User[]>(
|
||||
`${ENDPOINT.CMS_SERVICE.USER_ORGANIZATION}/move-ognz`,
|
||||
data,
|
||||
);
|
||||
return response.data;
|
||||
}
|
||||
}
|
||||
|
||||
export const UserOrganizationApi = new UserOrganizationApiService();
|
||||
@@ -0,0 +1,11 @@
|
||||
export { UserOrganizationApi } from "./api/user-organization-service";
|
||||
export {
|
||||
userOrganizationFormSchema,
|
||||
type TreeUserOrganization,
|
||||
type TreeUser,
|
||||
type UserOrganizationFormData,
|
||||
type UserOrganizationPayload,
|
||||
type User,
|
||||
type SearchUser,
|
||||
type MoveUserOrganizationPayload,
|
||||
} from "./model/user-organization-interface";
|
||||
@@ -0,0 +1,92 @@
|
||||
import { z } from "zod";
|
||||
import type { PageableList, PageableParams } from "@/shared/model";
|
||||
|
||||
export interface UserOrganizationParams extends PageableParams {
|
||||
keywordType?: string;
|
||||
keyword?: string;
|
||||
ognzSn?: number;
|
||||
userUnqId?: string;
|
||||
jbpsSeCd?: string;
|
||||
jbgdSeCd?: string;
|
||||
}
|
||||
|
||||
export interface SearchUserParams extends PageableParams {
|
||||
userNm?: string;
|
||||
ogdpSeCd?: string;
|
||||
}
|
||||
|
||||
export interface User {
|
||||
mode: string;
|
||||
ognzSn: number;
|
||||
userUnqId: string;
|
||||
userUnqNm?: string;
|
||||
jbpsSeCd: string;
|
||||
jbpsSeNm?: string;
|
||||
jbgdSeCd: string;
|
||||
jbgdSeNm?: string;
|
||||
sortSeq: number;
|
||||
mdfcnDt?: string;
|
||||
mdfr?: string;
|
||||
mdfrNm?: string;
|
||||
}
|
||||
|
||||
export interface SearchUser {
|
||||
userUnqId: string;
|
||||
userNm: string;
|
||||
ogdpSeCd: string;
|
||||
ogdpSeNm: string;
|
||||
regDt: string;
|
||||
}
|
||||
|
||||
export interface TreeUser {
|
||||
userUnqId: string;
|
||||
userNm: string;
|
||||
jbpsSeCd: string;
|
||||
jbgdSeCd: string;
|
||||
}
|
||||
|
||||
export interface TreeUserOrganization {
|
||||
ognzSn: number;
|
||||
upOgnzSn: number;
|
||||
ognzNm: string;
|
||||
users: TreeUser[];
|
||||
children: TreeUserOrganization[];
|
||||
}
|
||||
|
||||
export interface MoveUserOrganizationPayload {
|
||||
ognzSn: number;
|
||||
toOgnzSn: number;
|
||||
userUnqId: string;
|
||||
}
|
||||
|
||||
export const userOrganizationPayloadSchema = z.object({
|
||||
mode: z.string(),
|
||||
ognzSn: z.number(),
|
||||
userUnqId: z.string(),
|
||||
jbpsSeCd: z.string(),
|
||||
jbgdSeCd: z.string(),
|
||||
sortSeq: z.number(),
|
||||
});
|
||||
|
||||
export const userOrganizationFormSchema = z.object({
|
||||
userOrganization: z.array(userOrganizationPayloadSchema),
|
||||
});
|
||||
|
||||
export type UserOrganizationList = PageableList<User>;
|
||||
export type SearchUserList = PageableList<SearchUser>;
|
||||
export type UserOrganizationPayload = z.infer<
|
||||
typeof userOrganizationPayloadSchema
|
||||
>;
|
||||
export type UserOrganizationFormData = z.infer<
|
||||
typeof userOrganizationFormSchema
|
||||
>;
|
||||
|
||||
export interface UserOrganizationService {
|
||||
getUserOrganizationList(
|
||||
params: UserOrganizationParams,
|
||||
): Promise<UserOrganizationList>;
|
||||
getUserOrganizationTreeList(): Promise<TreeUserOrganization[]>;
|
||||
searchUser(params: SearchUserParams): Promise<SearchUserList>;
|
||||
saveUserOrganization(data: UserOrganizationPayload[]): Promise<User[]>;
|
||||
moveUserOrganization(data: MoveUserOrganizationPayload[]): Promise<User[]>;
|
||||
}
|
||||