|
1 | 1 | import * as React from 'react'; |
2 | 2 | import { TabComponent, TabItemDirective, TabItemsDirective } from '@syncfusion/ej2-react-navigations'; |
3 | | -import { Internationalization } from '@syncfusion/ej2-base'; |
4 | 3 | import { useLocation } from 'react-router-dom'; |
5 | | -import { EmployeeDetails } from '../../interface'; |
| 4 | +import { EmployeeDetails } from '../interface'; |
6 | 5 | import EmployeeLeave from './EmployeeLeave'; |
7 | 6 | import EmployeePayStub from './EmployeePayStub'; |
8 | 7 | import EmployeePayRoll from './EmployeePayRoll'; |
9 | | -import Employees from './Employees'; |
| 8 | +import { DataManager, UrlAdaptor, Query } from '@syncfusion/ej2-data'; |
10 | 9 |
|
11 | 10 | const EmployeeInfo = (props: { employeeData?: EmployeeDetails; userInfo?: EmployeeDetails }) => { |
12 | 11 | const location = useLocation(); |
13 | | - const employeeID = location.state?.employeeID; |
14 | | - let employeeData: EmployeeDetails = props.employeeData |
15 | | - ? props.employeeData |
16 | | - : employeeID |
17 | | - ? employeeID |
18 | | - : {}; |
19 | | - const userInfo: EmployeeDetails = location.state?.userInfo |
20 | | - ? location.state?.userInfo |
21 | | - : props.userInfo |
22 | | - ? props.userInfo |
23 | | - : {}; |
24 | | - let intl: Internationalization = new Internationalization(); |
| 12 | + const [defaultEmployee, setDefaultEmployee] = React.useState<EmployeeDetails | null>(null); |
| 13 | + const [loading, setLoading] = React.useState(true); |
| 14 | + |
| 15 | + // Fetch default employee on component mount if no employee is selected |
| 16 | + React.useEffect(() => { |
| 17 | + const fetchDefaultEmployee = async () => { |
| 18 | + setLoading(true); |
| 19 | + try { |
| 20 | + const dataManager = new DataManager({ |
| 21 | + url: 'https://ej2services.syncfusion.com/aspnet/development/api/EmployeesData', |
| 22 | + adaptor: new UrlAdaptor(), |
| 23 | + crossDomain: true, |
| 24 | + }); |
| 25 | + |
| 26 | + const query = new Query().take(1); |
| 27 | + const result: any = await dataManager.executeQuery(query); |
| 28 | + |
| 29 | + console.log('Fetched employee data:', result); |
| 30 | + |
| 31 | + // Handle different response formats |
| 32 | + let employeeArray: any[] = []; |
| 33 | + if (Array.isArray(result)) { |
| 34 | + employeeArray = result; |
| 35 | + } else if (result && Array.isArray(result.result)) { |
| 36 | + employeeArray = result.result; |
| 37 | + } |
| 38 | + |
| 39 | + if (employeeArray.length > 0) { |
| 40 | + setDefaultEmployee(employeeArray[0] as EmployeeDetails); |
| 41 | + } |
| 42 | + } catch (error) { |
| 43 | + console.error('Error fetching default employee:', error); |
| 44 | + } finally { |
| 45 | + setLoading(false); |
| 46 | + } |
| 47 | + }; |
| 48 | + |
| 49 | + // Only fetch if no employee is already provided |
| 50 | + const routeEmployee = (location.state as any)?.employeeID; |
| 51 | + if (!routeEmployee && !props.employeeData && !props.userInfo) { |
| 52 | + fetchDefaultEmployee(); |
| 53 | + } |
| 54 | + // Always set loading to false after checking - we have defaults |
| 55 | + setLoading(false); |
| 56 | + }, []); |
| 57 | + |
| 58 | + // Default employee - used if API fetch fails or takes time |
| 59 | + const defaultEmployeeData: EmployeeDetails = { |
| 60 | + Name: 'Michael Anderson', |
| 61 | + EmployeeCode: 'EMP100001', |
| 62 | + Branch: 'Tower 1', |
| 63 | + Team: 'Management', |
| 64 | + Designation: 'General Manager', |
| 65 | + TeamLead: 'Christopher Anderson', |
| 66 | + ManagerName: 'Christopher Anderson', |
| 67 | + |
| 68 | + DateOfJoining: new Date(new Date().getFullYear() - 20, 2, 1), |
| 69 | + FirstName: 'Michael', |
| 70 | + LastName: 'Anderson', |
| 71 | + FatherName: 'David Anderson', |
| 72 | + MotherName: 'Pamela Anderson', |
| 73 | + Gender: 'Male', |
| 74 | + BloodGroup: 'O+ve', |
| 75 | + MaritalStatus: 'Married', |
| 76 | + DOB: new Date(new Date().getFullYear() - 42, 3, 20), |
| 77 | + }; |
| 78 | + |
| 79 | + // Prefer explicit employee from route state, then prop, then fallback to defaultEmployee or hardcoded default |
| 80 | + const routeEmployee = (location.state as any)?.employeeID as any; |
| 81 | + const routeUser = (location.state as any)?.userInfo as any; |
| 82 | + const userInfo: EmployeeDetails = (routeUser as any) ?? (props.userInfo as any) ?? {} as any; |
| 83 | + let employeeData: EmployeeDetails = (routeEmployee as any) ?? (props.employeeData as any) ?? (userInfo as any) ?? (defaultEmployee as any) ?? defaultEmployeeData; |
25 | 84 | // Format the date to the desired output |
26 | | - const custom = { |
27 | | - day: "numeric", // Displays day as a number (e.g., 1) |
28 | | - month: "short", // Displays the short month name (e.g., Feb) |
29 | | - year: "numeric" // Displays the full year (e.g., 2005) |
| 85 | + const custom: Intl.DateTimeFormatOptions = { |
| 86 | + day: 'numeric', // Displays day as a number (e.g., 1) |
| 87 | + month: 'short', // Displays the short month name (e.g., Feb) |
| 88 | + year: 'numeric' // Displays the full year (e.g., 2005) |
30 | 89 | }; |
31 | | - let dateOfJoining = employeeData && employeeData.DateOfJoining.toLocaleDateString("en-GB", custom); |
32 | | - let dob: string = employeeData && employeeData.DOB.toLocaleDateString("en-GB", custom); |
33 | | - let experience: number = new Date().getFullYear() - employeeData.DateOfJoining.getFullYear(); |
34 | | - let experienceMonth: number = new Date().getMonth() - employeeData.DateOfJoining.getMonth(); |
| 90 | + |
| 91 | + // Normalize possible string dates to Date objects and guard for missing values |
| 92 | + const dojDate: Date | null = employeeData && (employeeData as any).DateOfJoining |
| 93 | + ? new Date((employeeData as any).DateOfJoining) |
| 94 | + : null; |
| 95 | + const dobDate: Date | null = employeeData && (employeeData as any).DOB |
| 96 | + ? new Date((employeeData as any).DOB) |
| 97 | + : null; |
| 98 | + |
| 99 | + const dateOfJoining: string = dojDate ? dojDate.toLocaleDateString('en-GB', custom) : '-'; |
| 100 | + const dob: string = dobDate ? dobDate.toLocaleDateString('en-GB', custom) : '-'; |
| 101 | + |
| 102 | + const now = new Date(); |
| 103 | + let experienceYears = 0; |
| 104 | + let experienceMonths = 0; |
| 105 | + if (dojDate) { |
| 106 | + let months = (now.getFullYear() - dojDate.getFullYear()) * 12 + (now.getMonth() - dojDate.getMonth()); |
| 107 | + if (months < 0) months = 0; |
| 108 | + experienceYears = Math.floor(months / 12); |
| 109 | + experienceMonths = months % 12; |
| 110 | + } |
35 | 111 | let headerText: Object[] = [ |
36 | 112 | { text: 'Official' }, |
37 | 113 | { text: 'Personal' }, |
@@ -95,7 +171,7 @@ const EmployeeInfo = (props: { employeeData?: EmployeeDetails; userInfo?: Employ |
95 | 171 | <div className="detail"> |
96 | 172 | <span className="sub-heading">Experience</span> |
97 | 173 | <span className="gap">:</span> |
98 | | - <span className="information">{experience} Years {experienceMonth} Months</span> |
| 174 | + <span className="information">{experienceYears} Years {experienceMonths} Months</span> |
99 | 175 | </div> |
100 | 176 | <div className="detail"> |
101 | 177 | <span className="sub-heading">User Work Shift</span> |
@@ -200,7 +276,16 @@ const EmployeeInfo = (props: { employeeData?: EmployeeDetails; userInfo?: Employ |
200 | 276 | ); |
201 | 277 | }; |
202 | 278 |
|
| 279 | + const hasEmployee = employeeData && Object.keys(employeeData as any).length > 0; |
| 280 | + |
203 | 281 | const overview = () => { |
| 282 | + if (loading) { |
| 283 | + return ( |
| 284 | + <div className="tab-content"> |
| 285 | + <div>Loading employee data...</div> |
| 286 | + </div> |
| 287 | + ); |
| 288 | + } |
204 | 289 | return ( |
205 | 290 | <div> |
206 | 291 | <div className="overview-header"> |
|
0 commit comments