Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 133 additions & 26 deletions Employee_Managment_App/src/components/EmployeeInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,37 +1,117 @@
import * as React from 'react';
import { TabComponent, TabItemDirective, TabItemsDirective } from '@syncfusion/ej2-react-navigations';
import { Internationalization } from '@syncfusion/ej2-base';
import { useLocation } from 'react-router-dom';
import { EmployeeDetails } from '../../interface';
import { EmployeeDetails } from '../interface';
import EmployeeLeave from './EmployeeLeave';
import EmployeePayStub from './EmployeePayStub';
import EmployeePayRoll from './EmployeePayRoll';
import Employees from './Employees';
import { DataManager, UrlAdaptor, Query } from '@syncfusion/ej2-data';



const EmployeeInfo = (props: { employeeData?: EmployeeDetails; userInfo?: EmployeeDetails }) => {
const location = useLocation();
const employeeID = location.state?.employeeID;
let employeeData: EmployeeDetails = props.employeeData
? props.employeeData
: employeeID
? employeeID
: {};
const userInfo: EmployeeDetails = location.state?.userInfo
? location.state?.userInfo
: props.userInfo
? props.userInfo
: {};
let intl: Internationalization = new Internationalization();
const [defaultEmployee, setDefaultEmployee] = React.useState<EmployeeDetails | null>(null);
const [loading, setLoading] = React.useState(true);

// Fetch default employee on component mount if no employee is selected
React.useEffect(() => {
const fetchDefaultEmployee = async () => {
setLoading(true);
try {
const dataManager = new DataManager({
url: 'https://ej2services.syncfusion.com/aspnet/development/api/EmployeesData',
adaptor: new UrlAdaptor(),
crossDomain: true,
});

const query = new Query().take(1);
const result: any = await dataManager.executeQuery(query);

console.log('Fetched employee data:', result);

// Handle different response formats
let employeeArray: any[] = [];
if (Array.isArray(result)) {
employeeArray = result;
} else if (result && Array.isArray(result.result)) {
employeeArray = result.result;
}

if (employeeArray.length > 0) {
setDefaultEmployee(employeeArray[0] as EmployeeDetails);
}
} catch (error) {
console.error('Error fetching default employee:', error);
} finally {
setLoading(false);
}
};

// Only fetch if no employee is already provided
const routeEmployee = (location.state as any)?.employeeID;
if (!routeEmployee && !props.employeeData && !props.userInfo) {
fetchDefaultEmployee();
}
// Always set loading to false after checking - we have defaults
setLoading(false);
}, []);

// Default employee - used if API fetch fails or takes time
const defaultEmployeeData: EmployeeDetails = {
Name: 'Michael Anderson',
EmployeeCode: 'EMP100001',
Branch: 'Tower 1',
Team: 'Management',
Designation: 'General Manager',
TeamLead: 'Christopher Anderson',
ManagerName: 'Christopher Anderson',
Mail: '[email protected]',
DateOfJoining: new Date(new Date().getFullYear() - 20, 2, 1),
FirstName: 'Michael',
LastName: 'Anderson',
FatherName: 'David Anderson',
MotherName: 'Pamela Anderson',
Gender: 'Male',
BloodGroup: 'O+ve',
MaritalStatus: 'Married',
DOB: new Date(new Date().getFullYear() - 42, 3, 20),
};



// Prefer explicit employee from route state, then prop, then fallback to defaultEmployee or hardcoded default
const routeEmployee = (location.state as any)?.employeeID as any;
const routeUser = (location.state as any)?.userInfo as any;
const userInfo: EmployeeDetails = (routeUser as any) ?? (props.userInfo as any) ?? {} as any;
let employeeData: EmployeeDetails = (routeEmployee as any) ?? (props.employeeData as any) ?? (userInfo as any) ?? (defaultEmployee as any) ?? defaultEmployeeData;
// Format the date to the desired output
const custom = {
day: "numeric", // Displays day as a number (e.g., 1)
month: "short", // Displays the short month name (e.g., Feb)
year: "numeric" // Displays the full year (e.g., 2005)
const custom: Intl.DateTimeFormatOptions = {
day: 'numeric', // Displays day as a number (e.g., 1)
month: 'short', // Displays the short month name (e.g., Feb)
year: 'numeric' // Displays the full year (e.g., 2005)
};
let dateOfJoining = employeeData && employeeData.DateOfJoining.toLocaleDateString("en-GB", custom);
let dob: string = employeeData && employeeData.DOB.toLocaleDateString("en-GB", custom);
let experience: number = new Date().getFullYear() - employeeData.DateOfJoining.getFullYear();
let experienceMonth: number = new Date().getMonth() - employeeData.DateOfJoining.getMonth();

// Normalize possible string dates to Date objects and guard for missing values
const dojDate: Date | null = employeeData && (employeeData as any).DateOfJoining
? new Date((employeeData as any).DateOfJoining)
: null;
const dobDate: Date | null = employeeData && (employeeData as any).DOB
? new Date((employeeData as any).DOB)
: null;

const dateOfJoining: string = dojDate ? dojDate.toLocaleDateString('en-GB', custom) : '-';
const dob: string = dobDate ? dobDate.toLocaleDateString('en-GB', custom) : '-';

const now = new Date();
let experienceYears = 0;
let experienceMonths = 0;
if (dojDate) {
let months = (now.getFullYear() - dojDate.getFullYear()) * 12 + (now.getMonth() - dojDate.getMonth());
if (months < 0) months = 0;
experienceYears = Math.floor(months / 12);
experienceMonths = months % 12;
}
let headerText: Object[] = [
{ text: 'Official' },
{ text: 'Personal' },
Expand Down Expand Up @@ -95,7 +175,7 @@ const EmployeeInfo = (props: { employeeData?: EmployeeDetails; userInfo?: Employ
<div className="detail">
<span className="sub-heading">Experience</span>
<span className="gap">:</span>
<span className="information">{experience} Years {experienceMonth} Months</span>
<span className="information">{experienceYears} Years {experienceMonths} Months</span>
</div>
<div className="detail">
<span className="sub-heading">User Work Shift</span>
Expand Down Expand Up @@ -200,7 +280,35 @@ const EmployeeInfo = (props: { employeeData?: EmployeeDetails; userInfo?: Employ
);
};

const hasEmployee = employeeData && Object.keys(employeeData as any).length > 0;

// Determine if private tabs should be visible
// Only show when viewing the logged-in user's own profile.
// With TopNav now passing EMP100001 as userInfo, this enables private tabs only when the selected
// employee is EMP100001.
const canSeePrivateTabs =
!!employeeData?.EmployeeCode &&
!!userInfo?.EmployeeCode &&
userInfo.EmployeeCode === employeeData.EmployeeCode;

<TabComponent heightAdjustMode="Auto" swipeMode="None" overflowMode='Scrollable'>
<TabItemsDirective>
<TabItemDirective header={headerText[0]} content={content0} />
{canSeePrivateTabs && <TabItemDirective header={headerText[1]} content={content1} />}
{canSeePrivateTabs && <TabItemDirective header={headerText[2]} content={content2} />}
{canSeePrivateTabs && <TabItemDirective header={headerText[3]} content={content3} />}
{canSeePrivateTabs && <TabItemDirective header={headerText[4]} content={content4} />}
</TabItemsDirective>
</TabComponent>

const overview = () => {
if (loading) {
return (
<div className="tab-content">
<div>Loading employee data...</div>
</div>
);
}
return (
<div>
<div className="overview-header">
Expand All @@ -227,7 +335,6 @@ const EmployeeInfo = (props: { employeeData?: EmployeeDetails; userInfo?: Employ
<div className="profile-data-designation">{employeeData.Designation}</div>
<div className='profile-data-Teamname'>{employeeData.Team}</div>
<div className="profile-data-supervisor">Supervisor: {employeeData.TeamLead}</div>
<div className="profile-data-branch">Branch: {employeeData.Branch}</div>
<div className="Profile-data-availability e-badge"> Available - {employeeData.Branch}</div>
</div>
</div>
Expand Down Expand Up @@ -277,4 +384,4 @@ const EmployeeInfo = (props: { employeeData?: EmployeeDetails; userInfo?: Employ
);
};

export default EmployeeInfo;
export default EmployeeInfo;
8 changes: 4 additions & 4 deletions Employee_Managment_App/src/components/EmployeeLeave.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -298,10 +298,10 @@ const statusTemplate = (args: any) => {
actionComplete={actionComplete}
>
<ColumnsDirective>
<ColumnDirective field="EmployeeCode" headerText="ID" visible={false} width="120" />
<ColumnDirective field="AttendanceID" headerText="Leave ID" isPrimaryKey={true} width="140" />
<ColumnDirective field="AbsenceType" headerText="Leave Type" width="120" template={leaveTypeTemplate} />
<ColumnDirective field="ShiftName" headerText="Shift Name" width="120" />
<ColumnDirective field="EmployeeCode" headerText="ID" visible={false} clipMode="EllipsisWithTooltip" width="120" />
<ColumnDirective field="AttendanceID" headerText="Leave ID" isPrimaryKey={true} clipMode="EllipsisWithTooltip" width="140" />
<ColumnDirective field="AbsenceType" headerText="Leave Type" width="120" clipMode="EllipsisWithTooltip" template={leaveTypeTemplate} />
<ColumnDirective field="ShiftName" headerText="Shift Name" clipMode="EllipsisWithTooltip" width="120" />
<ColumnDirective field="From" type="date" format="MMM d yyyy" textAlign="Right" width="120" />
<ColumnDirective field="To" type="date" format="MMM d yyyy" textAlign="Right" width="120" />
<ColumnDirective field="Days" headerText="Day(s)" textAlign="Right" width="120" />
Expand Down
Loading