import React, { useState, useEffect } from "react"; import { useNavigate, useParams, useLocation } from "react-router-dom"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { createRoot } from "react-dom/client"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Textarea } from "@/components/ui/textarea"; import { Dropdown, DropdownOption } from "@/components/ui/dropdown"; import { toast } from "@/lib/custom-toast"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Separator } from "@/components/ui/separator"; import { ChevronLeft, Loader2, ArrowLeft, LockIcon, InfoIcon } from "lucide-react"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"; import { employeeService, roleService } from "@/lib/api"; import { Employee, EmployeeRegistrationRequest, Role } from "@/types"; import Header from "@/components/layout/header"; import Sidebar from "@/components/layout/sidebar"; import { useIsMobile } from "@/hooks/use-mobile"; import { Skeleton } from "@/components/ui/skeleton"; import { useAuth } from "@/lib/auth-context"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; // Function to show toast with longer duration const showLongToast = (message: string, type: 'success' | 'error' = 'success') => { if (type === 'success') { toast.success(message, { duration: 10000 }); } else { toast.error(message, { duration: 10000 }); } }; const EmployeeEdit = () => { const { id } = useParams<{ id: string }>(); const navigate = useNavigate(); const location = useLocation(); const queryClient = useQueryClient(); const isMobile = useIsMobile(); const [isSidebarOpen, setIsSidebarOpen] = useState(!isMobile); const { userData } = useAuth(); // Close sidebar on mobile when route changes useEffect(() => { if (isMobile) { setIsSidebarOpen(false); } }, [location, isMobile]); // Update sidebar state when screen size changes useEffect(() => { setIsSidebarOpen(!isMobile); }, [isMobile]); // Check if user has HR or Admin permissions const hasHrAdminPermission = ['HR', 'Admin', 'Manager', 'Super Admin', 'HR Manager', 'Sr. HR Manager'].includes(userData?.roleName || ''); console.log('userData:', userData); console.log('roleName:', userData?.roleName); console.log('hasHrAdminPermission:', hasHrAdminPermission); // Check if editing own profile const [isOwnProfile, setIsOwnProfile] = useState(false); // Employee form state const [formData, setFormData] = useState({ id: 0, empCode: "", firstName: "", middleName: "", lastName: "", email: "", mobile: "", type: "", academics: "", financialData: "", description: "", passwordHash: "", roleId: 1 }); // Store the original restricted field values const [originalValues, setOriginalValues] = useState({ email: "", empCode: "", type: "", roleId: 0 }); // Fetch employee details const { data: employee, isLoading, error } = useQuery({ queryKey: ["employee", id], queryFn: () => employeeService.getById(Number(id)), enabled: !!id, staleTime: 300000 // 5 minutes }); // Fetch roles const { data: roles, isLoading: isLoadingRoles } = useQuery({ queryKey: ["roles"], queryFn: roleService.getAll, }); // Set form data when employee data is loaded useEffect(() => { if (employee) { setFormData({ ...employee, // Use an empty string for password since we don't want to pre-fill it passwordHash: "" }); // Store original values for restricted fields setOriginalValues({ email: employee.email, empCode: employee.empCode, type: employee.type, roleId: employee.roleId }); } }, [employee]); // Check if this is the user's own profile useEffect(() => { if (employee && userData) { setIsOwnProfile(employee.userId === userData.userId); } }, [employee, userData]); // Handle form input changes const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; // For restricted fields, only update if user has permission if (['email', 'empCode', 'type'].includes(name) && !hasHrAdminPermission) { return; } setFormData(prev => ({ ...prev, [name]: value })); }; // Handle select input changes const handleSelectChange = (name: string, value: string) => { setFormData(prev => ({ ...prev, [name]: value })); }; // Handle role selection const handleRoleChange = (value: string) => { // Only update role if user has permission if (!hasHrAdminPermission) { return; } setFormData(prev => ({ ...prev, roleId: parseInt(value) })); }; // Update mutation const updateMutation = useMutation({ mutationFn: (data: EmployeeRegistrationRequest) => { // If user doesn't have HR/Admin permission, restore original values for restricted fields if (!hasHrAdminPermission) { return employeeService.update({ ...data, email: originalValues.email, empCode: originalValues.empCode, type: originalValues.type, roleId: originalValues.roleId }); } return employeeService.update(data); }, onSuccess: (data) => { // Use response message if available const successMessage = data?.message || `Employee '${formData.firstName} ${formData.lastName}' has been successfully updated`; toast.success(successMessage); queryClient.invalidateQueries({ queryKey: ["employees"] }); queryClient.invalidateQueries({ queryKey: ["employee", id] }); // Navigate based on user role and profile ownership if (hasHrAdminPermission || !isOwnProfile) { navigate("/employees"); } else { // Regular users editing their own profile should go back to tasks navigate("/tasks"); } }, onError: (error: any) => { const errorMessage = error?.response?.data?.message || "Failed to update employee"; toast.error(errorMessage); } }); // Toggle sidebar const toggleSidebar = () => { setIsSidebarOpen(!isSidebarOpen); }; // Handle form submission const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); updateMutation.mutate(formData); }; // Handle navigation back const handleBack = () => { if (id) { navigate(`/employee/${id}`); } else { if (hasHrAdminPermission) { navigate("/employees"); } else { navigate("/tasks"); } } }; if (isLoading || isLoadingRoles) { return (
); } if (!employee) { return (

Employee not found

); } return (

Edit Employee

Update employee information

{!hasHrAdminPermission && (

Restricted Access

Some fields can only be edited by HR or Admin users. These fields are marked with a lock icon.

)}
Personal Information Edit the employee's personal details

Professional Details

{/*