ERP-node/frontend/app/(main)/admin/userMng/userAuthList/page.tsx

182 lines
5.7 KiB
TypeScript

"use client";
import React, { useState, useCallback, useEffect } from "react";
import { UserAuthTable } from "@/components/admin/UserAuthTable";
import { UserAuthEditModal } from "@/components/admin/UserAuthEditModal";
import { userAPI } from "@/lib/api/user";
import { useAuth } from "@/hooks/useAuth";
import { AlertCircle } from "lucide-react";
import { Button } from "@/components/ui/button";
import { ScrollToTop } from "@/components/common/ScrollToTop";
/**
* 사용자 권한 관리 페이지
* URL: /admin/userAuth
*
* 최고 관리자만 접근 가능
* 사용자별 권한 레벨(SUPER_ADMIN, COMPANY_ADMIN, USER 등) 관리
*/
export default function UserAuthPage() {
const { user: currentUser } = useAuth();
// 최고 관리자 여부
const isSuperAdmin = currentUser?.companyCode === "*" && currentUser?.userType === "SUPER_ADMIN";
// 상태 관리
const [users, setUsers] = useState<any[]>([]);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [paginationInfo, setPaginationInfo] = useState({
currentPage: 1,
pageSize: 20,
totalItems: 0,
totalPages: 0,
});
// 권한 변경 모달
const [authEditModal, setAuthEditModal] = useState({
isOpen: false,
user: null as any | null,
});
// 데이터 로드
const loadUsers = useCallback(
async (page: number = 1) => {
setIsLoading(true);
setError(null);
try {
const response = await userAPI.getList({
page,
size: paginationInfo.pageSize,
});
if (response.success && response.data) {
setUsers(response.data);
setPaginationInfo({
currentPage: response.currentPage || page,
pageSize: response.pageSize || paginationInfo.pageSize,
totalItems: response.total || 0,
totalPages: Math.ceil((response.total || 0) / (response.pageSize || paginationInfo.pageSize)),
});
} else {
setError(response.message || "사용자 목록을 불러오는데 실패했습니다.");
}
} catch (err) {
console.error("사용자 목록 로드 오류:", err);
setError("사용자 목록을 불러오는 중 오류가 발생했습니다.");
} finally {
setIsLoading(false);
}
},
[paginationInfo.pageSize],
);
useEffect(() => {
loadUsers(1);
}, []);
// 권한 변경 핸들러
const handleEditAuth = (user: any) => {
setAuthEditModal({
isOpen: true,
user,
});
};
// 권한 변경 모달 닫기
const handleAuthEditClose = () => {
setAuthEditModal({
isOpen: false,
user: null,
});
};
// 권한 변경 성공
const handleAuthEditSuccess = () => {
loadUsers(paginationInfo.currentPage);
handleAuthEditClose();
};
// 페이지 변경
const handlePageChange = (page: number) => {
loadUsers(page);
};
// 최고 관리자가 아닌 경우
if (!isSuperAdmin) {
return (
<div className="bg-background flex min-h-screen flex-col">
<div className="space-y-6 p-6">
<div className="space-y-2 border-b pb-4">
<h1 className="text-3xl font-bold tracking-tight"> </h1>
<p className="text-muted-foreground text-sm"> . ( )</p>
</div>
<div className="bg-card flex h-64 flex-col items-center justify-center rounded-lg border p-6 shadow-sm">
<AlertCircle className="text-destructive mb-4 h-12 w-12" />
<h3 className="mb-2 text-lg font-semibold"> </h3>
<p className="text-muted-foreground mb-4 text-center text-sm">
.
</p>
<Button variant="outline" onClick={() => window.history.back()}>
</Button>
</div>
</div>
<ScrollToTop />
</div>
);
}
return (
<div className="bg-background flex min-h-screen flex-col">
<div className="space-y-6 p-6">
{/* 페이지 헤더 */}
<div className="space-y-2 border-b pb-4">
<h1 className="text-3xl font-bold tracking-tight"> </h1>
<p className="text-muted-foreground text-sm"> . ( )</p>
</div>
{/* 에러 메시지 */}
{error && (
<div className="border-destructive/50 bg-destructive/10 rounded-lg border p-4">
<div className="flex items-center justify-between">
<p className="text-destructive text-sm font-semibold"> </p>
<button
onClick={() => setError(null)}
className="text-destructive hover:text-destructive/80 transition-colors"
aria-label="에러 메시지 닫기"
>
</button>
</div>
<p className="text-destructive/80 mt-1.5 text-sm">{error}</p>
</div>
)}
{/* 사용자 권한 테이블 */}
<UserAuthTable
users={users}
isLoading={isLoading}
paginationInfo={paginationInfo}
onEditAuth={handleEditAuth}
onPageChange={handlePageChange}
/>
{/* 권한 변경 모달 */}
<UserAuthEditModal
isOpen={authEditModal.isOpen}
onClose={handleAuthEditClose}
onSuccess={handleAuthEditSuccess}
user={authEditModal.user}
/>
</div>
{/* Scroll to Top 버튼 (모바일/태블릿 전용) */}
<ScrollToTop />
</div>
);
}