feat: 관리자 전용 직원 수정/삭제 모달 및 신규 파견 등록/종료 기능 추가

This commit is contained in:
pray4skylark
2026-09-30 16:36:48 +09:00
parent d5ad6600a0
commit 642402c948
4 changed files with 624 additions and 5 deletions
+44 -4
View File
@@ -8,6 +8,7 @@ import apiClient from '@/services/apiClient';
import { useCommonCodes } from '@/hooks/useCommonCodes';
import { useAuthStore } from '@/stores';
import type { Employee, RoleCode, EmpStatus, DispatchStatus } from '@/types';
import EmployeeEditModal from '@/components/employees/EmployeeEditModal';
const statusColor: Record<string, string> = {
ACTIVE: 'bg-status-resolved-bg text-status-resolved-text',
@@ -36,6 +37,7 @@ export default function EmployeesPage() {
// Detail Modal State
const [selectedEmployee, setSelectedEmployee] = useState<Employee | null>(null);
const [editingEmployee, setEditingEmployee] = useState<Employee | null>(null);
const [detailDispatch, setDetailDispatch] = useState<any[]>([]);
const [detailEquipment, setDetailEquipment] = useState<any[]>([]);
const [detailLoading, setDetailLoading] = useState(false);
@@ -580,7 +582,21 @@ export default function EmployeesPage() {
</td>
<td className="py-4 px-4 sm:px-6 text-text-muted truncate max-w-[150px] sm:max-w-none">{emp.email}</td>
<td className="py-4 px-4 sm:px-6">
<span className="text-xs text-text-muted">View details →</span>
<div className="flex items-center gap-2">
<span className="text-xs text-text-muted hover:text-primary transition-colors">상세 →</span>
{(user?.roleCode === 'ADMIN' || user?.roleCode === 'MANAGER') && (
<button
type="button"
onClick={(e) => {
e.stopPropagation();
setEditingEmployee(emp);
}}
className="px-2 py-1 bg-primary/10 text-primary hover:bg-primary/20 rounded text-xs font-semibold transition-colors"
>
수정
</button>
)}
</div>
</td>
</tr>
))}
@@ -606,9 +622,23 @@ export default function EmployeesPage() {
<p className="text-xs text-text-muted truncate">{roleLabel[emp.roleCode] || emp.roleCode}</p>
</div>
</div>
<span className={`text-[10px] font-medium px-2.5 py-1 rounded-full ${statusColor[emp.empStatus] || 'bg-gray-100 text-gray-600'}`}>
{emp.empStatus === 'ACTIVE' ? '재직' : emp.empStatus === 'ON_LEAVE' ? '휴직' : '퇴사'}
</span>
<div className="flex items-center gap-2">
<span className={`text-[10px] font-medium px-2.5 py-1 rounded-full ${statusColor[emp.empStatus] || 'bg-gray-100 text-gray-600'}`}>
{emp.empStatus === 'ACTIVE' ? '재직' : emp.empStatus === 'ON_LEAVE' ? '휴직' : '퇴사'}
</span>
{(user?.roleCode === 'ADMIN' || user?.roleCode === 'MANAGER') && (
<button
type="button"
onClick={(e) => {
e.stopPropagation();
setEditingEmployee(emp);
}}
className="px-2 py-1 bg-primary/10 text-primary hover:bg-primary/20 rounded text-xs font-semibold"
>
수정
</button>
)}
</div>
</div>
<div className="grid grid-cols-2 gap-2 text-xs text-text-muted">
<div className="truncate">Email: {emp.email}</div>
@@ -620,6 +650,16 @@ export default function EmployeesPage() {
</div>
</div>
</div>
{/* Employee Edit Modal */}
<EmployeeEditModal
isOpen={!!editingEmployee}
onClose={() => setEditingEmployee(null)}
employee={editingEmployee}
onSuccess={() => {
fetchEmployees();
}}
/>
</div>
);
}