feat: 사이트 반영 저장 api 작업

This commit is contained in:
2025-04-04 15:25:34 +09:00
parent 528cc39831
commit 7f4e973c5f
4 changed files with 55 additions and 7 deletions
@@ -6,6 +6,7 @@ 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";
const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {
const queryClient = new QueryClient();
@@ -16,6 +17,7 @@ const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => {
<AuthWrapper>
<MenuWrapper>{children}</MenuWrapper>
<AlertDialog />
<ConfirmDialog />
</AuthWrapper>
</ConfirmProvider>
</StoreProvider>
@@ -32,10 +32,17 @@ export const withModePostSchema = postSchema
})
.omit({
siteNm: true,
pstgTypeNm: true,
pstgPrdSeNm: true,
});
export const postingFormSchema = z.object({
pstg: z.array(withModePostSchema),
});
export type Post = z.infer<typeof postSchema>;
export type WithModePost = z.infer<typeof withModePostSchema>;
export type PostingFormData = z.infer<typeof postingFormSchema>;
export interface PostService {
getPostingHistory: (params: PostingParams) => Promise<PageableList<Post>>;
@@ -1,7 +1,9 @@
import dayjs from "dayjs";
import { useState } from "react";
import { zodResolver } from "@hookform/resolvers/zod";
import { useFieldArray, useForm } from "react-hook-form";
import { useQuery } from "@tanstack/react-query";
import { useMutation, useQuery } from "@tanstack/react-query";
import { useConfirm } from "@frontend-opensource/use-react-hooks";
import {
Dialog,
DialogTrigger,
@@ -19,13 +21,22 @@ import {
Checkbox,
Select,
DateRangePicker,
DialogClose,
DialogFooter,
} from "@common/components/ui";
import { cn } from "@common/components/lib";
import { CodeSelect } from "@/entities/code";
import { SiteApi, type Site } from "@/entities/site";
import type { PageableList } from "@/shared/model";
import { ENDPOINT } from "@/shared/config";
import { type PostingType } from "../model/posting-interface";
import { PostingApi } from "../api/posting-service";
import {
postingFormSchema,
type PostingFormData,
type PostingType,
type WithModePost,
} from "../model/posting-interface";
import { useAlertStore } from "@/shared/lib/use-alert-store";
type DateRange = {
from: string;
@@ -49,6 +60,8 @@ const POSTING_TYPE_LABEL = {
} as const;
function PostingDialog({ postingType, postingTargets }: PostingDialogProps) {
const { confirm } = useConfirm();
const { setMessage: alert } = useAlertStore((state) => state);
const [selectedRows, setSelectedRows] = useState<number[]>([]);
const [rememberPeriodCode, setRememberPeriodCode] = useState<
Record<string, string>
@@ -62,7 +75,16 @@ function PostingDialog({ postingType, postingTargets }: PostingDialogProps) {
queryFn: () => SiteApi.getSiteList({}),
});
const form = useForm();
const { mutateAsync: requestPosting } = useMutation({
mutationFn: (data: WithModePost[]) => PostingApi.requestPosting(data),
onSuccess: () => {
alert("저장되었습니다.");
},
});
const form = useForm<PostingFormData>({
resolver: zodResolver(postingFormSchema),
});
const { fields, append, replace } = useFieldArray({
control: form.control,
name: "pstg",
@@ -172,6 +194,13 @@ function PostingDialog({ postingType, postingTargets }: PostingDialogProps) {
});
};
const handleSave = async () => {
if (await confirm("저장하시겠습니까?")) {
const data = form.getValues("pstg");
await requestPosting(data);
}
};
return (
<Dialog onOpenChange={handleOpenChange}>
<DialogTrigger asChild>
@@ -196,7 +225,7 @@ function PostingDialog({ postingType, postingTargets }: PostingDialogProps) {
))}
</div>
</div>
<div className="m-2 max-h-[28rem] overflow-auto">
<div className="m-2 max-h-[30rem] overflow-auto">
<Table variant="secondary">
<colgroup>
<col width="10%" />
@@ -258,6 +287,16 @@ function PostingDialog({ postingType, postingTargets }: PostingDialogProps) {
</TableBody>
</Table>
</div>
<DialogFooter className="!justify-center">
<Button size="lg" onClick={handleSave}>
저장
</Button>
<DialogClose asChild>
<Button size="lg" color="white">
취소
</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
+3 -3
View File
@@ -9,7 +9,7 @@ import {
} from "@common/components/ui";
type ConfirmDialogProps = {
open: boolean;
open?: boolean;
confirmButtonProps?: ButtonProps & { label?: string };
cancelButtonProps?: ButtonProps & { label?: string };
};
@@ -19,9 +19,9 @@ function ConfirmDialog({
confirmButtonProps,
cancelButtonProps,
}: ConfirmDialogProps) {
const { message, onConfirm, onCancel } = useConfirm();
const { message, isOpen, onConfirm, onCancel } = useConfirm();
return (
<Dialog open={open} onOpenChange={onCancel}>
<Dialog open={open ?? isOpen} onOpenChange={onCancel}>
<DialogContent aria-describedby={undefined}>
<div className="py-10">
<p className="text-center text-[1.4rem] text-foreground">{message}</p>