feat: Add Resource Management module with HRM and Asset Management features
- Introduced FilePackageIcon component for resource management. - Updated MainScene to include resource management functionality. - Enhanced SideBarRight to support resource management display. - Created NavigateCategory component for category navigation in resource management. - Developed ResourceManagement component to switch between HRM and Asset Management views. - Implemented Hrm component to display employee details and tasks. - Added AssetManagement component to manage and display asset information. - Updated useModuleStore to include resourceManagement as a submodule. - Created resourceManagement.scss for styling the new module. - Removed hrm.scss as its styles have been integrated into resourceManagement.scss. - Updated main.scss to import resourceManagement styles instead of hrm.
This commit is contained in:
@@ -3,6 +3,7 @@ import Header from "./Header";
|
||||
import useModuleStore, { useSubModuleStore } from "../../../store/useModuleStore";
|
||||
import {
|
||||
AnalysisIcon,
|
||||
FilePackageIcon,
|
||||
MechanicsIcon,
|
||||
PropertiesIcon,
|
||||
SimulationIcon,
|
||||
@@ -33,7 +34,7 @@ import FloorProperties from "./properties/FloorProperties";
|
||||
import SelectedWallProperties from "./properties/SelectedWallProperties";
|
||||
import SelectedFloorProperties from "./properties/SelectedFloorProperties";
|
||||
import DecalTransformation from "./decals/DecalTransformation";
|
||||
import Hrm from "./hrm/Hrm";
|
||||
import ResourceManagement from "./resourceManagement/ResourceManagement";
|
||||
|
||||
type DisplayComponent =
|
||||
| "versionHistory"
|
||||
@@ -50,6 +51,7 @@ type DisplayComponent =
|
||||
| "analysis"
|
||||
| "visualization"
|
||||
| "decals"
|
||||
| "resourceManagement"
|
||||
| "none";
|
||||
|
||||
const SideBarRight: React.FC = () => {
|
||||
@@ -105,6 +107,19 @@ const SideBarRight: React.FC = () => {
|
||||
setDisplayComponent("analysis");
|
||||
return;
|
||||
}
|
||||
if (subModule === "resourceManagement") {
|
||||
setDisplayComponent("resourceManagement");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (activeModule === "simulation" || activeModule === "builder") {
|
||||
if (subModule === "resourceManagement") {
|
||||
setDisplayComponent("resourceManagement");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (subModule === "properties" && activeModule !== "visualization") {
|
||||
@@ -129,7 +144,7 @@ const SideBarRight: React.FC = () => {
|
||||
return;
|
||||
}
|
||||
if (!selectedFloorItem && !selectedFloor && !selectedWall && !selectedSubCategory) {
|
||||
console.log('selectedSubCategory: ', selectedSubCategory);
|
||||
|
||||
|
||||
if (toolMode === "Aisle") {
|
||||
setDisplayComponent("aisleProperties");
|
||||
@@ -146,6 +161,7 @@ const SideBarRight: React.FC = () => {
|
||||
setDisplayComponent("globalProperties");
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (subModule === "zoneProperties" && (activeModule === "builder" || activeModule === "simulation")) {
|
||||
@@ -157,6 +173,7 @@ const SideBarRight: React.FC = () => {
|
||||
}, [viewVersionHistory, activeModule, subModule, isVersionSaved, selectedFloorItem, selectedWall, selectedFloor, selectedAisle, toolMode, selectedSubCategory]);
|
||||
|
||||
const renderComponent = () => {
|
||||
|
||||
switch (displayComponent) {
|
||||
case "versionHistory":
|
||||
return <VersionHistory />;
|
||||
@@ -186,6 +203,8 @@ const SideBarRight: React.FC = () => {
|
||||
return <Visualization />;
|
||||
case "decals":
|
||||
return <DecalTransformation />;
|
||||
case "resourceManagement":
|
||||
return <ResourceManagement />;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -201,19 +220,23 @@ const SideBarRight: React.FC = () => {
|
||||
<>
|
||||
{(!isVersionSaved || activeModule !== "simulation") && (
|
||||
<div className="sidebar-actions-container">
|
||||
|
||||
{activeModule !== "simulation" && (
|
||||
<button
|
||||
id="sidebar-action-list-properties"
|
||||
className={`sidebar-action-list ${subModule === "properties" ? "active" : ""}`}
|
||||
onClick={() => {
|
||||
setSubModule("properties");
|
||||
setVersionHistoryVisible(false);
|
||||
}}
|
||||
>
|
||||
<div className="tooltip">properties</div>
|
||||
<PropertiesIcon isActive={subModule === "properties"} />
|
||||
</button>
|
||||
<>
|
||||
<button
|
||||
id="sidebar-action-list-properties"
|
||||
className={`sidebar-action-list ${subModule === "properties" ? "active" : ""}`}
|
||||
onClick={() => {
|
||||
setSubModule("properties");
|
||||
setVersionHistoryVisible(false);
|
||||
}}
|
||||
>
|
||||
<div className="tooltip">properties</div>
|
||||
<PropertiesIcon isActive={subModule === "properties"} />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{activeModule === "simulation" && (
|
||||
<>
|
||||
<button
|
||||
@@ -251,6 +274,21 @@ const SideBarRight: React.FC = () => {
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
{(activeModule === "builder" || activeModule === "simulation") && (
|
||||
<button
|
||||
id="sidebar-action-list-properties"
|
||||
className={`sidebar-action-list ${subModule === "resourceManagement" ? "active" : ""}`}
|
||||
onClick={() => {
|
||||
setSubModule("resourceManagement");
|
||||
setVersionHistoryVisible(false);
|
||||
}}
|
||||
>
|
||||
<div className="tooltip">Resource Management</div>
|
||||
<FilePackageIcon isActive={subModule === "resourceManagement"} />
|
||||
</button>
|
||||
)}
|
||||
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -258,7 +296,7 @@ const SideBarRight: React.FC = () => {
|
||||
<div className="sidebar-right-container">
|
||||
<div className="sidebar-right-content-container">
|
||||
{renderComponent()}
|
||||
{/* <Hrm /> */}
|
||||
{/* <ResourceManagement /> */}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
|
||||
interface Props {
|
||||
category: string[];
|
||||
selectedCategory: string;
|
||||
setSelectedCategory: (cat: string) => void;
|
||||
}
|
||||
|
||||
const NavigateCategory = ({ category, selectedCategory, setSelectedCategory }: Props) => {
|
||||
return (
|
||||
<div className="category-wrapper">
|
||||
{category.map((cat) => (
|
||||
<div
|
||||
key={cat}
|
||||
className={`category ${selectedCategory === cat ? "active" : ''}`}
|
||||
onClick={() => setSelectedCategory(cat)}
|
||||
>
|
||||
{cat}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NavigateCategory;
|
||||
@@ -0,0 +1,48 @@
|
||||
import React, { useState } from 'react'
|
||||
|
||||
import Search from '../../../ui/inputs/Search'
|
||||
import RegularDropDown from '../../../ui/inputs/RegularDropDown'
|
||||
import Hrm from './hrm/Hrm'
|
||||
import AssetManagement from './hrm/assetManagement/AssetManagement'
|
||||
|
||||
const ResourceManagement = () => {
|
||||
type DisplayType = "hrm" | "asset";
|
||||
const [selectType, setSelectType] = useState("assetManagement")
|
||||
|
||||
const [display, setDisplay] = useState<DisplayType>("asset");
|
||||
|
||||
return (
|
||||
<div className='resourceManagement-container'>
|
||||
<div className="navigation-wrapper">
|
||||
<div
|
||||
className={`navigation ${selectType === "assetManagement" ? "active" : ""}`}
|
||||
onClick={() => setSelectType("assetManagement")}
|
||||
>
|
||||
Asset Management
|
||||
</div>
|
||||
<div
|
||||
className={`navigation ${selectType === "peopleOperation" ? "active" : ""}`}
|
||||
onClick={() => setSelectType("peopleOperation")}
|
||||
>
|
||||
People Operations
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="search-container">
|
||||
<Search onChange={() => { }} />
|
||||
<div className="select-catagory">
|
||||
<RegularDropDown
|
||||
header={"floor"}
|
||||
options={["floor"]} // Pass layout names as options
|
||||
onSelect={() => { }}
|
||||
search={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{selectType === "assetManagement" ? <AssetManagement /> : <Hrm />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ResourceManagement
|
||||
@@ -1,11 +1,10 @@
|
||||
import React, { useState } from 'react'
|
||||
import Search from '../../../ui/inputs/Search'
|
||||
import RegularDropDown from '../../../ui/inputs/RegularDropDown'
|
||||
import { ClockThreeIcon, HourGlassIcon, ListTaskIcon, LocationPinIcon, SlectedTickIcon, TargetIcon } from '../../../icons/ExportCommonIcons'
|
||||
import Search from '../../../../ui/inputs/Search'
|
||||
import RegularDropDown from '../../../../ui/inputs/RegularDropDown'
|
||||
import { ClockThreeIcon, HourGlassIcon, ListTaskIcon, LocationPinIcon, SlectedTickIcon, TargetIcon } from '../../../../icons/ExportCommonIcons'
|
||||
import NavigateCatagory from '../NavigateCatagory'
|
||||
|
||||
const Hrm = () => {
|
||||
const [selectType, setSelectType] = useState("assetManagement")
|
||||
const [selectcatogory, setSelectCatogary] = useState("All People")
|
||||
const employee_details = [
|
||||
{
|
||||
"employee": {
|
||||
@@ -93,50 +92,23 @@ const Hrm = () => {
|
||||
}
|
||||
]
|
||||
|
||||
const [selectedCard, setSelectedCard] = useState(0);
|
||||
console.log('selectedCard: ', selectedCard);
|
||||
|
||||
return (
|
||||
<div className='hrm-container'>
|
||||
<div className="navigation-wrapper">
|
||||
<div
|
||||
className={`navigation ${selectType === "assetManagement" ? "active" : ""}`}
|
||||
onClick={() => setSelectType("assetManagement")}
|
||||
>
|
||||
Asset Management
|
||||
</div>
|
||||
<div
|
||||
className={`navigation ${selectType === "peopleOperation" ? "active" : ""}`}
|
||||
onClick={() => setSelectType("peopleOperation")}
|
||||
>
|
||||
People Operations
|
||||
</div>
|
||||
</div>
|
||||
<>
|
||||
{/* <NavigateCatagory
|
||||
category={["All People", "Technician", "Operator", "Supervisor", "Safety Officer"]}
|
||||
selectedCategory={selectedCategory}
|
||||
setSelectedCategory={setSelectedCategory}
|
||||
/> */}
|
||||
|
||||
<div className="search-container">
|
||||
<Search onChange={() => { }} />
|
||||
<div className="select-catagory">
|
||||
<RegularDropDown
|
||||
header={"floor"}
|
||||
options={["floor"]} // Pass layout names as options
|
||||
onSelect={() => { }}
|
||||
search={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="catagories-wrapper">
|
||||
{["All People", "Technician", "Operator", "Supervisor", "Safety Officer"].map((cat, index) => (
|
||||
<div
|
||||
key={cat}
|
||||
className={`catagory ${selectcatogory === cat ? "active" : ''}`}
|
||||
onClick={() => setSelectCatogary(cat)}
|
||||
>
|
||||
{cat}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="analysis-container">
|
||||
<div className='hrm-container assetManagement-wrapper'>
|
||||
{employee_details.map((employee, index) => (
|
||||
<div className="analysis-wrapper">
|
||||
<div
|
||||
className={`analysis-wrapper ${selectedCard === index ? "active" : ""}`}
|
||||
onClick={() => setSelectedCard(index)}
|
||||
>
|
||||
<header>
|
||||
<div className="user-details">
|
||||
<div className="user-image-wrapper">
|
||||
@@ -206,7 +178,7 @@ const Hrm = () => {
|
||||
|
||||
<div className="stat-wrapper">
|
||||
<span className="stat-icon"><TargetIcon /></span>
|
||||
<span>Completed Tasks:</span>
|
||||
<span>Cost per hr:</span>
|
||||
</div>
|
||||
|
||||
<span className='stat-value'>{employee.task.completed_tasks}</span>
|
||||
@@ -233,7 +205,7 @@ const Hrm = () => {
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
import React, { useState } from 'react'
|
||||
import NavigateCatagory from '../../NavigateCatagory'
|
||||
import { EyeIcon, ForkLiftIcon, KebabIcon, LocationPinIcon, RightHalfFillCircleIcon } from '../../../../../icons/ExportCommonIcons';
|
||||
import assetImage from "../../../../../../assets/image/asset-image.png"
|
||||
const AssetManagement = () => {
|
||||
const [selectedCategory, setSelectedCategory] = useState("All Assets");
|
||||
const [expandedAssetId, setExpandedAssetId] = useState<string | null>(null);
|
||||
|
||||
const dummyAssets = [
|
||||
{
|
||||
id: '1',
|
||||
name: 'Forklift Model X200',
|
||||
model: 'FLK-0025',
|
||||
status: 'Online',
|
||||
usageRate: 89,
|
||||
level: 'Level 1',
|
||||
image: assetImage,
|
||||
description: 'Electric forklift used for moving goods and materials in warehouse operations.',
|
||||
cost: 122000,
|
||||
count: 5,
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
name: 'Warehouse Robot WR-300',
|
||||
model: 'WRB-3001',
|
||||
status: 'Online',
|
||||
usageRate: 76,
|
||||
level: 'Level 2',
|
||||
image: assetImage,
|
||||
description: 'Automated robot for handling packages and inventory in the warehouse.',
|
||||
cost: 85000,
|
||||
count: 3,
|
||||
},
|
||||
{
|
||||
id: '3',
|
||||
name: 'Conveyor Belt System CB-150',
|
||||
model: 'CBS-150X',
|
||||
status: 'Online',
|
||||
usageRate: 95,
|
||||
level: 'Level 3',
|
||||
image: assetImage,
|
||||
description: 'High-speed conveyor belt system for efficient material handling.',
|
||||
cost: 45000,
|
||||
count: 2,
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* <NavigateCatagory
|
||||
category={["All Assets", "Machines", "Workstation", "Vehicles"]}
|
||||
selectedCategory={selectedCategory}
|
||||
setSelectedCategory={setSelectedCategory}
|
||||
/> */}
|
||||
|
||||
<div className='assetManagement-container'>
|
||||
{dummyAssets.map((asset, index) => (
|
||||
<div className={`assetManagement-wrapper ${expandedAssetId === asset.id ? "openViewMore" : ""}`}>
|
||||
<header>
|
||||
<div className="header-wrapper">
|
||||
|
||||
{expandedAssetId === asset.id ?
|
||||
<img className='asset-image' src={asset.image} alt="" />
|
||||
:
|
||||
<div className="icon"><ForkLiftIcon /></div>
|
||||
}
|
||||
<div className="asset-details-container">
|
||||
<div className="asset-details">
|
||||
<div className="asset-name">{asset.name}</div>
|
||||
<div className="asset-model">{asset.model}</div>
|
||||
</div>
|
||||
<div className="asset-status-wrapper">
|
||||
<div className={`indication ${asset.status}`}></div>
|
||||
<div className="status">{asset.status}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{expandedAssetId === asset.id && <div className="description">{asset.description}</div>}
|
||||
</header>
|
||||
|
||||
{expandedAssetId === asset.id ? (
|
||||
<div className="asset-estimate">
|
||||
<div className="asset-estimate__unit-cost">
|
||||
<div className="asset-estimate__label">Cost of Asset</div>
|
||||
<div className="asset-estimate__value">₹ 1,22,000</div>
|
||||
</div>
|
||||
|
||||
<div className="asset-estimate__breakdown">
|
||||
<div className="asset-estimate__in-scene">
|
||||
<div className="asset-estimate__label">In Scene</div>
|
||||
<div className="asset-estimate__value">5 items</div>
|
||||
</div>
|
||||
<div className="asset-estimate__total-cost">
|
||||
<div className="asset-estimate__label">Total Cost</div>
|
||||
<div className="asset-estimate__value">₹ 6,10,000</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="asset-estimate__view-button" onClick={() => setExpandedAssetId(null)}>
|
||||
<EyeIcon isClosed={false} />
|
||||
<div className="asset-estimate__view-text">View in Scene</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
) : (
|
||||
<div className="asset-contents">
|
||||
<div className="asset-wrapper">
|
||||
<div className="key-wrapper">
|
||||
<div className="icon"><RightHalfFillCircleIcon /></div>
|
||||
<div className="key">Usage rate</div>
|
||||
</div>
|
||||
<div className="progress-wrapper">
|
||||
<div className="progress-bar">
|
||||
<div
|
||||
className="filled-value"
|
||||
style={{ width: `${asset.usageRate}%` }}
|
||||
></div>
|
||||
</div>
|
||||
<div className="usage-value">{asset.usageRate}%</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="asset-wrapper">
|
||||
<div className="key-wrapper">
|
||||
<div className="icon"><LocationPinIcon /></div>
|
||||
<div className="key">{asset.level}</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="viewMore"
|
||||
onClick={() =>
|
||||
setExpandedAssetId(expandedAssetId === asset.id ? null : asset.id)
|
||||
}
|
||||
>
|
||||
<div className="value">{expandedAssetId === asset.id ? "View Less" : "View More"}</div>
|
||||
<div className="icon"><KebabIcon /></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
)}
|
||||
|
||||
</div>
|
||||
|
||||
))}
|
||||
</div >
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AssetManagement
|
||||
|
||||
|
||||
Reference in New Issue
Block a user