refactor: update navigation path and enhance asset/worker management components

This commit is contained in:
2025-08-25 10:28:11 +05:30
parent c86509e812
commit fad9c74730
4 changed files with 252 additions and 136 deletions

View File

@@ -64,7 +64,7 @@ const SidePannel: React.FC<SidePannelProps> = ({ setActiveTab, activeTab }) => {
const handleResponse = (data: any) => { const handleResponse = (data: any) => {
if (data.message === "Project created successfully") { if (data.message === "Project created successfully") {
setLoadingProgress(1) setLoadingProgress(1)
navigate(`/${data.data.projectId}`); navigate(`/projects/${data.data.projectId}`);
} }
projectSocket.off("v1-project:response:add", handleResponse); // Clean up projectSocket.off("v1-project:response:add", handleResponse); // Clean up
}; };

View File

@@ -30,14 +30,6 @@ const ResourceManagement = () => {
<div className="search-container"> <div className="search-container">
<Search onChange={() => { }} /> <Search onChange={() => { }} />
<div className="select-catagory">
<RegularDropDown
header={"floor"}
options={["floor"]} // Pass layout names as options
onSelect={() => { }}
search={false}
/>
</div>
</div> </div>
{selectType === "assetManagement" ? <AssetManagement /> : <Hrm />} {selectType === "assetManagement" ? <AssetManagement /> : <Hrm />}

View File

@@ -1,96 +1,156 @@
import { useState } from 'react' import { useEffect, useState } from 'react'
import { ClockThreeIcon, LocationPinIcon, TargetIcon } from '../../../../icons/ExportCommonIcons' import { ClockThreeIcon, LocationPinIcon, TargetIcon } from '../../../../icons/ExportCommonIcons'
import { useSceneContext } from '../../../../../modules/scene/sceneContext';
import { useProductContext } from '../../../../../modules/simulation/products/productContext';
import RenameInput from '../../../../ui/inputs/RenameInput';
// import NavigateCatagory from '../NavigateCatagory' // import NavigateCatagory from '../NavigateCatagory'
const Hrm = () => { const Hrm = () => {
const [selectedCard, setSelectedCard] = useState(0); const [selectedCard, setSelectedCard] = useState(0);
const [workers, setWorkers] = useState<any[]>([]);
const employee_details = [ const { productStore } = useSceneContext();
{ const { products, getProductById } = productStore();
"employee": { const { selectedProductStore } = useProductContext();
image: "", const { selectedProduct } = selectedProductStore();
"name": "John Doe",
"employee_id": "HR-204",
"status": "Active",
}, useEffect(() => {
"task": { if (selectedProduct) {
"status": "Ongoing", const productDetails = getProductById(selectedProduct.productUuid);
"title": "Inspecting Machine X", const workerDetails = productDetails?.eventDatas || [];
"location": {
"floor": 4,
"zone": "B"
},
"planned_time_hours": 6,
"time_spent_hours": 2,
"total_tasks": 12,
"completed_tasks": 3
},
"actions": [
"Assign Task",
"Reassign Task",
"Pause",
"Emergency Stop"
],
"location": "Floor 4 . Zone B"
},
{
"employee": {
image: "",
"name": "Alice Smith",
"employee_id": "HR-205",
"status": "Active",
}, const formattedWorkers = workerDetails
"task": { .filter((worker: any) => worker.type === "human")
"status": "Ongoing", .map((worker: any, index: number) => ({
"title": "Calibrating Sensor Y", employee: {
"location": { image: "",
"floor": 2, name: worker.modelName,
"zone": "A" employee_id: `HR-${204 + index}`,
}, status: "Active",
"planned_time_hours": 4, },
"time_spent_hours": 1.5, task: {
"total_tasks": 10, status: "Ongoing",
"completed_tasks": 2 title: worker.taskTitle || "No Task Assigned",
}, location: {
"actions": [ floor: worker.floor || 0,
"Assign Task", zone: worker.zone || "N/A"
"Reassign Task", },
"Pause", planned_time_hours: worker.plannedTime || 0,
"Emergency Stop" time_spent_hours: worker.timeSpent || 0,
], total_tasks: worker.totalTasks || 0,
"location": "Floor 4 . Zone B" completed_tasks: worker.completedTasks || 0
}, },
{ actions: [
"employee": { "Assign Task",
image: "", "Reassign Task",
"name": "Michael Lee", "Pause",
"employee_id": "HR-206", "Emergency Stop"
"status": "Active", ],
location: `Floor ${worker.floor || "-"} . Zone ${worker.zone || "-"}`
}));
setWorkers(formattedWorkers);
}
}, [selectedProduct, getProductById]);
useEffect(() => {
// console.log("Workers data updated:", workers);
}, [workers]);
// const employee_details = [
// {
// "employee": {
// image: "",
// "name": "John Doe",
// "employee_id": "HR-204",
// "status": "Active",
// },
// "task": {
// "status": "Ongoing",
// "title": "Inspecting Machine X",
// "location": {
// "floor": 4,
// "zone": "B"
// },
// "planned_time_hours": 6,
// "time_spent_hours": 2,
// "total_tasks": 12,
// "completed_tasks": 3
// },
// "actions": [
// "Assign Task",
// "Reassign Task",
// "Pause",
// "Emergency Stop"
// ],
// "location": "Floor 4 . Zone B"
// },
// {
// "employee": {
// image: "",
// "name": "Alice Smith",
// "employee_id": "HR-205",
// "status": "Active",
// },
// "task": {
// "status": "Ongoing",
// "title": "Calibrating Sensor Y",
// "location": {
// "floor": 2,
// "zone": "A"
// },
// "planned_time_hours": 4,
// "time_spent_hours": 1.5,
// "total_tasks": 10,
// "completed_tasks": 2
// },
// "actions": [
// "Assign Task",
// "Reassign Task",
// "Pause",
// "Emergency Stop"
// ],
// "location": "Floor 4 . Zone B"
// },
// {
// "employee": {
// image: "",
// "name": "Michael Lee",
// "employee_id": "HR-206",
// "status": "Active",
// },
// "task": {
// "status": "Ongoing",
// "title": "Testing Conveyor Belt Z",
// "location": {
// "floor": 5,
// "zone": "C"
// },
// "planned_time_hours": 5,
// "time_spent_hours": 3,
// "total_tasks": 8,
// "completed_tasks": 5
// },
// "actions": [
// "Assign Task",
// "Reassign Task",
// "Pause",
// "Emergency Stop"
// ],
// "location": "Floor 4 . Zone B"
// },
// ]
function handleRenameWorker(newName: string) {
// console.log('newName: ', newName);
}
},
"task": {
"status": "Ongoing",
"title": "Testing Conveyor Belt Z",
"location": {
"floor": 5,
"zone": "C"
},
"planned_time_hours": 5,
"time_spent_hours": 3,
"total_tasks": 8,
"completed_tasks": 5
},
"actions": [
"Assign Task",
"Reassign Task",
"Pause",
"Emergency Stop"
],
"location": "Floor 4 . Zone B"
},
]
return ( return (
<> <>
@@ -101,7 +161,7 @@ const Hrm = () => {
/> */} /> */}
<div className='hrm-container assetManagement-wrapper'> <div className='hrm-container assetManagement-wrapper'>
{employee_details.map((employee, index) => ( {workers.map((employee, index) => (
<div <div
className={`analysis-wrapper ${selectedCard === index ? "active" : ""}`} className={`analysis-wrapper ${selectedCard === index ? "active" : ""}`}
onClick={() => setSelectedCard(index)} onClick={() => setSelectedCard(index)}
@@ -114,7 +174,8 @@ const Hrm = () => {
<div className={`status ${employee.employee.status}`}></div> <div className={`status ${employee.employee.status}`}></div>
</div> </div>
<div className="details"> <div className="details">
<div className="employee-name">{employee.employee.name}</div> {/* <div className="employee-name">{employee.employee.name}</div> */}
<RenameInput value={employee.employee.name} onRename={handleRenameWorker} />
<div className="employee-id">{employee.employee.employee_id}</div> <div className="employee-id">{employee.employee.employee_id}</div>
</div> </div>
</div> </div>

View File

@@ -1,49 +1,105 @@
import { useState } from 'react' import { useEffect, useState } from 'react'
// import NavigateCatagory from '../../NavigateCatagory' // import NavigateCatagory from '../../NavigateCatagory'
import { EyeIcon, ForkLiftIcon, KebabIcon, LocationPinIcon, RightHalfFillCircleIcon } from '../../../../../icons/ExportCommonIcons'; import { EyeIcon, ForkLiftIcon, KebabIcon, LocationPinIcon, RightHalfFillCircleIcon } from '../../../../../icons/ExportCommonIcons';
import assetImage from "../../../../../../assets/image/asset-image.png" import assetImage from "../../../../../../assets/image/asset-image.png"
import { useSceneContext } from '../../../../../../modules/scene/sceneContext';
import { useProductContext } from '../../../../../../modules/simulation/products/productContext';
import RenameInput from '../../../../../ui/inputs/RenameInput';
const AssetManagement = () => { const AssetManagement = () => {
// const [selectedCategory, setSelectedCategory] = useState("All Assets"); // const [selectedCategory, setSelectedCategory] = useState("All Assets");
const [expandedAssetId, setExpandedAssetId] = useState<string | null>(null); const [expandedAssetId, setExpandedAssetId] = useState<string | null>(null);
const [assets, setAssets] = useState<any[]>([]);
const dummyAssets = [ const { productStore } = useSceneContext();
{ const { products, getProductById } = productStore();
id: '1', const { selectedProductStore } = useProductContext();
name: 'Forklift Model X200', const { selectedProduct } = selectedProductStore();
model: 'FLK-0025',
status: 'Online',
usageRate: 15,
level: 'Level 1', useEffect(() => {
image: assetImage, if (selectedProduct) {
description: 'Electric forklift used for moving goods and materials in warehouse operations.', const productDetails = getProductById(selectedProduct.productUuid);
cost: 122000, const productAssets = productDetails?.eventDatas || [];
count: 5, const grouped: Record<string, any> = {};
}, productAssets.forEach((asset: any) => {
{ if (asset.type === "storageUnit" || asset.type === "human") return;
id: '2', if (!grouped[asset.modelName]) {
name: 'Warehouse Robot WR-300', grouped[asset.modelName] = {
model: 'WRB-3001', id: asset.assetId,
status: 'Online', name: asset.modelName,
usageRate: 50, model: asset.modelCode || "N/A",
level: 'Level 2', status: asset.status || "Online",
image: assetImage, usageRate: asset.usageRate || 15,
description: 'Automated robot for handling packages and inventory in the warehouse.', level: asset.level || "Level 1",
cost: 85000, image: assetImage,
count: 3, description: asset.description || "No description",
}, cost: asset.cost || 0,
{ count: 1,
id: '3', };
name: 'Conveyor Belt System CB-150', } else {
model: 'CBS-150X', grouped[asset.modelName].count += 1;
status: 'Online', }
usageRate: 95, });
level: 'Level 3',
image: assetImage, setAssets(Object.values(grouped));
description: 'High-speed conveyor belt system for efficient material handling.', }
cost: 45000, }, [selectedProduct]);
count: 2,
}, function handleRenameAsset(newName: string) {
]; // console.log('newName: ', newName);
// if (expandedAssetId) {
// setAssets(prevAssets =>
// prevAssets.map(asset =>
// asset.id === expandedAssetId ? { ...asset, name: newName } : asset
// )
// );
// }
}
useEffect(() => {
}, [assets]);
// const dummyAssets = [
// {
// id: '1',
// name: 'Forklift Model X200',
// model: 'FLK-0025',
// status: 'Online',
// usageRate: 15,
// 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: 50,
// 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 ( return (
@@ -55,7 +111,7 @@ const AssetManagement = () => {
/> */} /> */}
<div className='assetManagement-container assetManagement-wrapper'> <div className='assetManagement-container assetManagement-wrapper'>
{dummyAssets.map((asset, index) => ( {assets.map((asset, index) => (
<div className={`assetManagement-card-wrapper ${expandedAssetId === asset.id ? "openViewMore" : ""}`} key={index}> <div className={`assetManagement-card-wrapper ${expandedAssetId === asset.id ? "openViewMore" : ""}`} key={index}>
<header> <header>
<div className="header-wrapper"> <div className="header-wrapper">
@@ -67,7 +123,14 @@ const AssetManagement = () => {
} }
<div className="asset-details-container"> <div className="asset-details-container">
<div className="asset-details"> <div className="asset-details">
<div className="asset-name">{asset.name}</div> {/* <div className="asset-name">{asset.name}</div> */}
<RenameInput value={asset.name} onRename={handleRenameAsset} />
{asset.count !== 1 && <div>
<span className="asset-id-label">x</span>
<span className="asset-id">{asset.count}</span>
</div>}
<div className="asset-model">{asset.model}</div> <div className="asset-model">{asset.model}</div>
</div> </div>
<div className="asset-status-wrapper"> <div className="asset-status-wrapper">