feat: 권한 버튼 생성 및 적용

This commit is contained in:
2025-05-20 17:33:28 +09:00
parent 6f2a5c6308
commit bc4513d3fc
8 changed files with 118 additions and 82 deletions
@@ -1 +1,2 @@
export { AuthorityButton } from "./ui/authority-button";
export { ManagementAuthorityDialog } from "./ui/management-authority-dialog";
@@ -0,0 +1,26 @@
import { useMenuStore } from "@/shared/lib";
import { Button, cn, type ButtonProps } from "@common/components";
import type { PageMenuAuthority } from "../model/menu-authority-interface";
type AuthorityButtonProps = {
authority: keyof PageMenuAuthority;
} & ButtonProps;
function AuthorityButton({
authority,
className,
children,
...props
}: AuthorityButtonProps) {
const pageMenuAuthority = useMenuStore((state) => state.pageMenuAuthority);
const isAuthority = pageMenuAuthority?.[authority] === "Y";
return (
<Button className={cn(className, !isAuthority && "hidden")} {...props}>
{children}
</Button>
);
}
export { AuthorityButton };
@@ -25,10 +25,10 @@ const MenuWrapper = ({ children }: { children: React.ReactNode }) => {
const getPageMenuAuthority = async () => {
const menuCd = getCookie("menu-code-key");
if (!menuCd) return;
const pageMenuAuthority = await MenuAuthorityApi.getPageMenuAuthority(
const response = await MenuAuthorityApi.getPageMenuAuthority(
parseInt(menuCd),
);
return pageMenuAuthority;
return response;
};
const checkInquiryAuthority = () => {
@@ -40,9 +40,8 @@ const MenuWrapper = ({ children }: { children: React.ReactNode }) => {
const currentMenu = await getCurrentMenuInfo();
if (currentMenu) setCurrentMenuInfo(currentMenu);
const pageMenuAuthority = await getPageMenuAuthority();
if (pageMenuAuthority?.length)
setPageMenuAuthority(pageMenuAuthority[0]!);
const response = await getPageMenuAuthority();
if (response?.length) setPageMenuAuthority(response[0]!);
})();
}, []);
@@ -26,6 +26,7 @@ import {
cn,
} from "@common/components";
import { CodeSelect } from "@/entities/code/@x/posting";
import { AuthorityButton } from "@/entities/menu-authority";
import { SiteApi, type Site } from "@/entities/site/@x/posting";
import type { PageableList } from "@/shared/model";
import { ENDPOINT } from "@/shared/config";
@@ -218,10 +219,14 @@ function PostingDialog({ postingType, postingTargets }: PostingDialogProps) {
return (
<Dialog onOpenChange={handleOpenChange}>
<DialogTrigger asChild>
<Button color="emerald" disabled={!postingTargets.length}>
<AuthorityButton
authority="mngAuthrtYn"
color="emerald"
disabled={!postingTargets.length}
>
<i className="diveicon di-layer" />
사이트반영
</Button>
</AuthorityButton>
</DialogTrigger>
<DialogContent className="max-w-[68rem]" aria-describedby={undefined}>
<DialogHeader>
+16 -15
View File
@@ -22,6 +22,7 @@ import {
} from "@common/components";
import { AttachmentApi } from "@/entities/attachment";
import { PostApi, type PostParams } from "@/entities/post";
import { AuthorityButton } from "@/entities/menu-authority";
import { useAlertStore, useMenuStore, usePrompt } from "@/shared/lib";
import { ENDPOINT } from "@/shared/config";
@@ -30,7 +31,7 @@ function FaqPage({ bbsId }: { bbsId: string }) {
const pathname = usePathname();
const { prompt } = usePrompt();
const { setMessage: alert } = useAlertStore((state) => state);
const { bbsInfo, pageMenuAuthority } = useMenuStore((state) => state);
const { bbsInfo } = useMenuStore((state) => state);
const [postParams, setPostParams] = useState<PostParams>({
keywordType: "title",
@@ -140,20 +141,20 @@ function FaqPage({ bbsId }: { bbsId: string }) {
<div className="flex w-full items-center justify-between">
<h3 className="text-2xl font-medium text-label">콘텐츠 목록</h3>
<div className="flex gap-2">
{pageMenuAuthority?.regAuthrtYn === "Y" && (
<Button onClick={() => router.push(`${pathname}/register`)}>
등록
</Button>
)}
{pageMenuAuthority?.delAuthrtYn === "Y" && (
<Button
color="red"
onClick={onSelectedPostDelete}
disabled={!selectedPostNumbers.length}
>
선택삭제
</Button>
)}
<AuthorityButton
authority="regAuthrtYn"
onClick={() => router.push(`${pathname}/register`)}
>
등록
</AuthorityButton>
<AuthorityButton
authority="delAuthrtYn"
color="red"
onClick={onSelectedPostDelete}
disabled={!selectedPostNumbers.length}
>
선택삭제
</AuthorityButton>
</div>
</div>
</div>
@@ -12,6 +12,7 @@ import {
} from "@common/components";
import type { Board } from "@/entities/board";
import type { MovePost } from "@/entities/post";
import { AuthorityButton } from "@/entities/menu-authority";
type MovePostDialogProps = {
selectedPosts: MovePost[];
@@ -36,9 +37,12 @@ function MovePostDialog({
return (
<Dialog>
<DialogTrigger asChild>
<Button color="emerald" disabled={!selectedPosts.length}>
<AuthorityButton
authority="mngAuthrtYn"
disabled={!selectedPosts.length}
>
게시물 이동
</Button>
</AuthorityButton>
</DialogTrigger>
<DialogContent>
<p className="pt-8 text-center text-[1.3rem]">
+42 -41
View File
@@ -30,8 +30,9 @@ import {
type RecentPost,
type RecentPostParams,
} from "@/entities/post";
import { useAlertStore, useMenuStore, usePrompt } from "@/shared/lib";
import { BoardApi } from "@/entities/board";
import { AuthorityButton } from "@/entities/menu-authority";
import { useAlertStore, usePrompt } from "@/shared/lib";
import { ENDPOINT } from "@/shared/config";
import { columns } from "../model/table-columns";
import { MovePostDialog } from "./move-post-dialog";
@@ -46,7 +47,6 @@ function RecentPage() {
const { prompt } = usePrompt();
const { confirm } = useConfirm();
const { setMessage: alert } = useAlertStore((state) => state);
const { pageMenuAuthority } = useMenuStore((state) => state);
const [dateRange, setDateRange] = useState<DateRange>();
const [pagination, setPagination] = useState<PaginationState>({
pageIndex: 0,
@@ -272,45 +272,46 @@ function RecentPage() {
<div className="flex w-full items-center justify-between">
<h3 className="text-2xl font-medium text-label">콘텐츠 목록</h3>
<div className="flex gap-2">
{pageMenuAuthority?.mngAuthrtYn === "Y" &&
(isDeletePostData ? (
<>
<Button
color="emerald"
onClick={onRestorePost}
disabled={!isSelectedRow}
>
게시물 복원
</Button>
<Button
color="red"
onClick={onHardDeletePost}
disabled={!isSelectedRow}
>
완전삭제
</Button>
</>
) : (
<>
<MovePostDialog
selectedPosts={table
.getFilteredSelectedRowModel()
.rows.map((row) => ({
fromBbsId: row.original.bbsId,
pstNo: row.original.pstNo,
}))}
boardList={boardList?.content ?? []}
onMovePost={movePost}
/>
<Button
color="red"
onClick={onSoftDeletePost}
disabled={!isSelectedRow}
>
선택삭제
</Button>
</>
))}
{isDeletePostData ? (
<>
<AuthorityButton
authority="mngAuthrtYn"
onClick={onRestorePost}
disabled={!isSelectedRow}
>
게시물 복원
</AuthorityButton>
<AuthorityButton
authority="delAuthrtYn"
color="red"
onClick={onHardDeletePost}
disabled={!isSelectedRow}
>
완전삭제
</AuthorityButton>
</>
) : (
<>
<MovePostDialog
selectedPosts={table
.getFilteredSelectedRowModel()
.rows.map((row) => ({
fromBbsId: row.original.bbsId,
pstNo: row.original.pstNo,
}))}
boardList={boardList?.content ?? []}
onMovePost={movePost}
/>
<AuthorityButton
authority="delAuthrtYn"
color="red"
onClick={onSoftDeletePost}
disabled={!isSelectedRow}
>
선택삭제
</AuthorityButton>
</>
)}
<Select
value={table.getState().pagination.pageSize.toString()}
onValueChange={(value) => {
+16 -17
View File
@@ -22,6 +22,7 @@ import {
Skeleton,
} from "@common/components";
import { BoardApi } from "@/entities/board";
import { AuthorityButton } from "@/entities/menu-authority";
import { PostApi, type Post, type PostParams } from "@/entities/post";
import { ENDPOINT } from "@/shared/config";
import { useMenuStore, usePrompt } from "@/shared/lib";
@@ -33,9 +34,7 @@ function PostPage({ bbsId }: { bbsId: string }) {
const router = useRouter();
const pathname = usePathname();
const { prompt } = usePrompt();
const { bbsInfo, pageMenuAuthority, setBbsInfo } = useMenuStore(
(state) => state,
);
const { bbsInfo, setBbsInfo } = useMenuStore((state) => state);
const thumbRefs = useRef<Map<number, string>>(new Map());
const [postParams, setPostParams] = useState<PostParams>({
@@ -174,20 +173,20 @@ function PostPage({ bbsId }: { bbsId: string }) {
<div className="flex w-full items-center justify-between">
<h3 className="text-2xl font-medium text-label">콘텐츠 목록</h3>
<div className="flex gap-2">
{pageMenuAuthority?.regAuthrtYn === "Y" && (
<Button onClick={() => router.push(`${pathname}/register`)}>
등록
</Button>
)}
{pageMenuAuthority?.delAuthrtYn === "Y" && (
<Button
color="red"
onClick={onPostDelete}
disabled={!table.getFilteredSelectedRowModel().rows.length}
>
선택삭제
</Button>
)}
<AuthorityButton
authority="regAuthrtYn"
onClick={() => router.push(`${pathname}/register`)}
>
등록
</AuthorityButton>
<AuthorityButton
authority="delAuthrtYn"
color="red"
onClick={onPostDelete}
disabled={!table.getFilteredSelectedRowModel().rows.length}
>
선택삭제
</AuthorityButton>
<Select
value={table.getState().pagination.pageSize.toString()}
onValueChange={(value) => {