first commit
This commit is contained in:
25
app/src/components/layout/sidebarLeft/Assets.tsx
Normal file
25
app/src/components/layout/sidebarLeft/Assets.tsx
Normal file
@@ -0,0 +1,25 @@
|
||||
import React, { useState } from "react";
|
||||
import Search from "../../ui/inputs/Search";
|
||||
|
||||
const Assets: React.FC = () => {
|
||||
const [searchValue, setSearchValue] = useState<string>("");
|
||||
|
||||
const handleSearchChange = (value: string) => {
|
||||
setSearchValue(value);
|
||||
console.log(value); // Log the search value if needed
|
||||
};
|
||||
return (
|
||||
<div className="assets-container">
|
||||
<Search onChange={handleSearchChange} />
|
||||
{searchValue ? (
|
||||
<div className="searched-content">
|
||||
<p>Results for "{searchValue}"</p>
|
||||
</div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Assets;
|
||||
31
app/src/components/layout/sidebarLeft/Header.tsx
Normal file
31
app/src/components/layout/sidebarLeft/Header.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import React from "react";
|
||||
import { ToggleSidebarIcon } from "../../icons/HeaderIcons";
|
||||
import { LogoIcon } from "../../icons/Logo";
|
||||
import FileMenu from "../../ui/FileMenu";
|
||||
import useToggleStore from "../../../store/useUIToggleStore";
|
||||
|
||||
const Header: React.FC = () => {
|
||||
const { toggleUI, setToggleUI } = useToggleStore();
|
||||
return (
|
||||
<div className="header-container">
|
||||
<div className="header-content">
|
||||
<div className="logo-container">
|
||||
<LogoIcon />
|
||||
</div>
|
||||
<div className="header-title">
|
||||
<FileMenu />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className={`toggle-sidebar-ui-button ${!toggleUI ? "active" : ""}`}
|
||||
onClick={() => {
|
||||
setToggleUI(!toggleUI);
|
||||
}}
|
||||
>
|
||||
<ToggleSidebarIcon />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
48
app/src/components/layout/sidebarLeft/Outline.tsx
Normal file
48
app/src/components/layout/sidebarLeft/Outline.tsx
Normal file
@@ -0,0 +1,48 @@
|
||||
import React, { useState } from "react";
|
||||
import Search from "../../ui/inputs/Search";
|
||||
import DropDownList from "../../ui/list/DropDownList";
|
||||
|
||||
const Outline: React.FC = () => {
|
||||
const [searchValue, setSearchValue] = useState<string>("");
|
||||
|
||||
const handleSearchChange = (value: string) => {
|
||||
setSearchValue(value);
|
||||
console.log(value); // Log the search value if needed
|
||||
};
|
||||
|
||||
const dropdownItems = [
|
||||
{ id: "1", name: "Ground Floor" },
|
||||
{ id: "2", name: "Floor 1" },
|
||||
]; // Example dropdown items
|
||||
|
||||
return (
|
||||
<div className="outline-container">
|
||||
<Search onChange={handleSearchChange} />
|
||||
{searchValue ? (
|
||||
<div className="searched-content">
|
||||
<p>Results for "{searchValue}"</p>
|
||||
</div>
|
||||
) : (
|
||||
<div className="outline-content-container">
|
||||
<DropDownList
|
||||
value="Layers"
|
||||
items={dropdownItems}
|
||||
defaultOpen={true}
|
||||
showKebabMenu={false}
|
||||
showFocusIcon={true}
|
||||
/>
|
||||
<DropDownList
|
||||
value="Scene"
|
||||
items={dropdownItems}
|
||||
defaultOpen={true}
|
||||
listType="outline"
|
||||
showKebabMenu={false}
|
||||
showAddIcon={false}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Outline;
|
||||
70
app/src/components/layout/sidebarLeft/SideBarLeft.tsx
Normal file
70
app/src/components/layout/sidebarLeft/SideBarLeft.tsx
Normal file
@@ -0,0 +1,70 @@
|
||||
import React, { useEffect, useState } from "react";
|
||||
import ToggleHeader from "../../ui/inputs/ToggleHeader";
|
||||
import Outline from "./Outline";
|
||||
import Header from "./Header";
|
||||
import useToggleStore from "../../../store/useUIToggleStore";
|
||||
import Assets from "./Assets";
|
||||
import useModuleStore from "../../../store/useModuleStore";
|
||||
import Widgets from "./visualization/widgets/Widgets";
|
||||
import Templates from "./visualization/Templates";
|
||||
import Search from "../../ui/inputs/Search";
|
||||
|
||||
const SideBarLeft: React.FC = () => {
|
||||
const [activeOption, setActiveOption] = useState("Widgets");
|
||||
|
||||
const { toggleUI } = useToggleStore();
|
||||
const { activeModule } = useModuleStore();
|
||||
|
||||
// Reset activeOption whenever activeModule changes
|
||||
useEffect(() => {
|
||||
setActiveOption("Outline");
|
||||
if (activeModule === "visualization") setActiveOption("Widgets");
|
||||
}, [activeModule]);
|
||||
|
||||
const handleToggleClick = (option: string) => {
|
||||
setActiveOption(option); // Update the active option
|
||||
};
|
||||
|
||||
const handleSearchChange = (value: string) => {
|
||||
// Log the search value for now
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="sidebar-left-wrapper">
|
||||
<Header />
|
||||
{toggleUI && (
|
||||
<div className="sidebar-left-container">
|
||||
{activeModule === "visualization" ? (
|
||||
<>
|
||||
<ToggleHeader
|
||||
options={["Widgets", "Templates"]}
|
||||
activeOption={activeOption}
|
||||
handleClick={handleToggleClick}
|
||||
/>
|
||||
<Search onChange={handleSearchChange} />
|
||||
<div className="sidebar-left-content-container">
|
||||
{activeOption === "Widgets" ? <Widgets /> : <Templates />}
|
||||
</div>
|
||||
</>
|
||||
) : activeModule === "market" ? (
|
||||
<></>
|
||||
) : (
|
||||
<>
|
||||
<ToggleHeader
|
||||
options={["Outline", "Assets"]}
|
||||
activeOption={activeOption}
|
||||
handleClick={handleToggleClick}
|
||||
/>
|
||||
<div className="sidebar-left-content-container">
|
||||
{activeOption === "Outline" ? <Outline /> : <Assets />}
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SideBarLeft;
|
||||
@@ -0,0 +1,125 @@
|
||||
import useTemplateStore from "../../../../store/useTemplateStore";
|
||||
import { useSelectedZoneStore } from "../../../../store/useZoneStore";
|
||||
|
||||
const Templates = () => {
|
||||
const { templates, removeTemplate } = useTemplateStore();
|
||||
const { setSelectedZone } = useSelectedZoneStore();
|
||||
|
||||
console.log("templates: ", templates);
|
||||
const handleDeleteTemplate = (id: string) => {
|
||||
removeTemplate(id);
|
||||
};
|
||||
|
||||
const handleLoadTemplate = (template: any) => {
|
||||
setSelectedZone((prev) => ({
|
||||
...prev,
|
||||
panelOrder: template.panelOrder,
|
||||
activeSides: Array.from(
|
||||
new Set([...prev.activeSides, ...template.panelOrder])
|
||||
),
|
||||
widgets: template.widgets,
|
||||
}));
|
||||
};
|
||||
|
||||
return (
|
||||
<div
|
||||
className="template-list"
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(auto-fill, minmax(180px, 1fr))",
|
||||
gap: "1rem",
|
||||
padding: "1rem",
|
||||
}}
|
||||
>
|
||||
{templates.map((template) => (
|
||||
<div
|
||||
key={template.id}
|
||||
className="template-item"
|
||||
style={{
|
||||
border: "1px solid #e0e0e0",
|
||||
borderRadius: "8px",
|
||||
padding: "1rem",
|
||||
transition: "box-shadow 0.3s ease",
|
||||
}}
|
||||
>
|
||||
{template.snapshot && (
|
||||
<div style={{ position: "relative", paddingBottom: "56.25%" }}>
|
||||
{" "}
|
||||
{/* 16:9 aspect ratio */}
|
||||
<img
|
||||
src={template.snapshot} // Corrected from template.image to template.snapshot
|
||||
alt={`${template.name} preview`}
|
||||
style={{
|
||||
position: "absolute",
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
objectFit: "contain",
|
||||
borderRadius: "4px",
|
||||
cursor: "pointer",
|
||||
transition: "transform 0.3s ease",
|
||||
// ':hover': {
|
||||
// transform: 'scale(1.05)'
|
||||
// }
|
||||
}}
|
||||
onClick={() => handleLoadTemplate(template)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
marginTop: "0.5rem",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
onClick={() => handleLoadTemplate(template)}
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
fontWeight: "500",
|
||||
// ':hover': {
|
||||
// textDecoration: 'underline'
|
||||
// }
|
||||
}}
|
||||
>
|
||||
{template.name}
|
||||
</div>
|
||||
<button
|
||||
onClick={() => handleDeleteTemplate(template.id)}
|
||||
style={{
|
||||
padding: "0.25rem 0.5rem",
|
||||
background: "#ff4444",
|
||||
color: "white",
|
||||
border: "none",
|
||||
borderRadius: "4px",
|
||||
cursor: "pointer",
|
||||
transition: "opacity 0.3s ease",
|
||||
// ':hover': {
|
||||
// opacity: 0.8
|
||||
// }
|
||||
}}
|
||||
aria-label="Delete template"
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
{templates.length === 0 && (
|
||||
<div
|
||||
style={{
|
||||
textAlign: "center",
|
||||
color: "#666",
|
||||
padding: "2rem",
|
||||
gridColumn: "1 / -1",
|
||||
}}
|
||||
>
|
||||
No saved templates yet. Create one in the visualization view!
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Templates;
|
||||
@@ -0,0 +1,130 @@
|
||||
import React, { useEffect, useRef, useMemo } from "react";
|
||||
import { Chart } from "chart.js/auto";
|
||||
// import { useThemeStore } from "../../../../../store/useThemeStore";
|
||||
|
||||
// Define Props Interface
|
||||
interface ChartComponentProps {
|
||||
type: any; // Type of chart (e.g., "bar", "line", etc.)
|
||||
title: string; // Title of the chart
|
||||
fontFamily?: string; // Optional font family for the chart title
|
||||
fontSize?: string; // Optional font size for the chart title
|
||||
fontWeight?: "Light" | "Regular" | "Bold"; // Optional font weight for the chart title
|
||||
data: {
|
||||
labels: string[]; // Labels for the x-axis
|
||||
datasets: {
|
||||
data: number[]; // Data points for the chart
|
||||
backgroundColor: string; // Background color for the chart
|
||||
borderColor: string; // Border color for the chart
|
||||
borderWidth: number; // Border width for the chart
|
||||
}[];
|
||||
}; // Data for the chart
|
||||
}
|
||||
|
||||
const ChartComponent = ({
|
||||
type,
|
||||
title,
|
||||
fontFamily,
|
||||
fontSize,
|
||||
fontWeight = "Regular", // Default to "Regular"
|
||||
data: propsData,
|
||||
}: ChartComponentProps) => {
|
||||
const canvasRef = useRef<HTMLCanvasElement>(null);
|
||||
// const { themeColor } = useThemeStore();
|
||||
|
||||
// Memoize Theme Colors to Prevent Unnecessary Recalculations
|
||||
// const buttonActionColor = useMemo(
|
||||
// () => themeColor[0] || "#5c87df",
|
||||
// [themeColor]
|
||||
// );
|
||||
// const buttonAbortColor = useMemo(
|
||||
// () => themeColor[1] || "#ffffff",
|
||||
// [themeColor]
|
||||
// );
|
||||
|
||||
// Memoize Font Weight Mapping
|
||||
const chartFontWeightMap = useMemo(
|
||||
() => ({
|
||||
Light: "lighter" as const,
|
||||
Regular: "normal" as const,
|
||||
Bold: "bold" as const,
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
||||
// Parse and Memoize Font Size
|
||||
const fontSizeValue = useMemo(
|
||||
() => (fontSize ? parseInt(fontSize) : 12),
|
||||
[fontSize]
|
||||
);
|
||||
|
||||
// Determine and Memoize Font Weight
|
||||
const fontWeightValue = useMemo(
|
||||
() => chartFontWeightMap[fontWeight],
|
||||
[fontWeight, chartFontWeightMap]
|
||||
);
|
||||
|
||||
// Memoize Chart Font Style
|
||||
const chartFontStyle = useMemo(
|
||||
() => ({
|
||||
family: fontFamily || "Arial",
|
||||
size: fontSizeValue,
|
||||
weight: fontWeightValue,
|
||||
color: "#2B3344",
|
||||
}),
|
||||
[fontFamily, fontSizeValue, fontWeightValue]
|
||||
);
|
||||
|
||||
// Memoize Chart Data
|
||||
const data = useMemo(() => propsData, [propsData]);
|
||||
|
||||
// Memoize Chart Options
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: title,
|
||||
font: chartFontStyle,
|
||||
align: "start", // Left align the title
|
||||
padding: {
|
||||
top: 10, // Add padding above the title
|
||||
bottom: 20, // Add padding between the title and the chart
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
[title, chartFontStyle]
|
||||
);
|
||||
|
||||
// Initialize Chart on Component Mount
|
||||
useEffect(() => {
|
||||
if (!canvasRef.current) return;
|
||||
|
||||
const ctx = canvasRef.current.getContext("2d");
|
||||
if (!ctx) return;
|
||||
|
||||
const chart = new Chart(ctx, { type, data, options });
|
||||
|
||||
// Cleanup: Destroy the chart instance when the component unmounts
|
||||
return () => chart.destroy();
|
||||
}, [type, data, options]); // Only recreate the chart when these dependencies change
|
||||
|
||||
return <canvas ref={canvasRef} style={{ width: "100%", height: "100%" }} />;
|
||||
};
|
||||
|
||||
export default React.memo(ChartComponent, (prevProps, nextProps) => {
|
||||
// Custom comparison function to prevent unnecessary re-renders
|
||||
return (
|
||||
prevProps.type === nextProps.type &&
|
||||
prevProps.title === nextProps.title &&
|
||||
prevProps.fontFamily === nextProps.fontFamily &&
|
||||
prevProps.fontSize === nextProps.fontSize &&
|
||||
prevProps.fontWeight === nextProps.fontWeight &&
|
||||
JSON.stringify(prevProps.data) === JSON.stringify(nextProps.data)
|
||||
);
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { useState } from "react";
|
||||
import ToggleHeader from "../../../../ui/inputs/ToggleHeader";
|
||||
import Widgets2D from "./Widgets2D";
|
||||
import Widgets3D from "./Widgets3D";
|
||||
import WidgetsFloating from "./WidgetsFloating";
|
||||
|
||||
const Widgets = () => {
|
||||
const [activeOption, setActiveOption] = useState("Floating");
|
||||
|
||||
const handleToggleClick = (option: string) => {
|
||||
setActiveOption(option);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="widget-left-sideBar">
|
||||
<ToggleHeader
|
||||
options={["2D", "3D", "Floating"]}
|
||||
activeOption={activeOption}
|
||||
handleClick={handleToggleClick}
|
||||
/>
|
||||
{activeOption === "2D" && <Widgets2D />}
|
||||
{activeOption === "3D" && <Widgets3D />}
|
||||
{activeOption === "Floating" && <WidgetsFloating />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Widgets;
|
||||
@@ -0,0 +1,141 @@
|
||||
import React from "react";
|
||||
import { useWidgetStore } from "../../../../../store/useWidgetStore";
|
||||
import { ChartType } from "chart.js/auto";
|
||||
import ChartComponent from "./ChartComponent";
|
||||
import { StockIncreseIcon } from "../../../../icons/RealTimeVisulationIcons";
|
||||
|
||||
const chartTypes: ChartType[] = [
|
||||
"bar",
|
||||
"line",
|
||||
"pie",
|
||||
"doughnut",
|
||||
"radar",
|
||||
"polarArea",
|
||||
];
|
||||
|
||||
const sampleData = {
|
||||
labels: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"],
|
||||
datasets: [
|
||||
{
|
||||
data: [65, 59, 80, 81, 56, 55, 40],
|
||||
backgroundColor: "#6f42c1",
|
||||
borderColor: "#ffffff",
|
||||
borderWidth: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
interface WidgetProps {
|
||||
type: ChartType;
|
||||
index: number;
|
||||
title: string;
|
||||
}
|
||||
|
||||
const ChartWidget: React.FC<WidgetProps> = ({ type, index, title }) => {
|
||||
const { setDraggedAsset } = useWidgetStore((state) => state);
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`chart chart-${index + 1}`}
|
||||
draggable
|
||||
onDragStart={() => {
|
||||
setDraggedAsset({
|
||||
type,
|
||||
id: `widget-${index + 1}`,
|
||||
title,
|
||||
panel: "top",
|
||||
data: sampleData,
|
||||
});
|
||||
}}
|
||||
onDragEnd={() => setDraggedAsset(null)}
|
||||
>
|
||||
<ChartComponent type={type} title={title} data={sampleData} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const ProgressBarWidget = ({
|
||||
id,
|
||||
title,
|
||||
data,
|
||||
}: {
|
||||
id: string;
|
||||
title: string;
|
||||
data: any;
|
||||
}) => {
|
||||
const { setDraggedAsset } = useWidgetStore((state) => state);
|
||||
|
||||
return (
|
||||
<div
|
||||
className="chart progressBar"
|
||||
draggable
|
||||
onDragStart={() => {
|
||||
setDraggedAsset({
|
||||
type: "progress",
|
||||
id,
|
||||
title,
|
||||
panel: "top",
|
||||
data,
|
||||
});
|
||||
}}
|
||||
onDragEnd={() => setDraggedAsset(null)}
|
||||
>
|
||||
<div className="header">{title}</div>
|
||||
{data.stocks.map((stock: any, index: number) => (
|
||||
<div className="stock" key={index}>
|
||||
<span className="stock-item">
|
||||
<span className="stockValues">
|
||||
<div className="key">{stock.key}</div>
|
||||
<div className="value">{stock.value}</div>
|
||||
</span>
|
||||
<div className="stock-description">{stock.description}</div>
|
||||
</span>
|
||||
<div className="icon">
|
||||
<StockIncreseIcon />
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Widgets2D = () => {
|
||||
return (
|
||||
<div className="widget2D">
|
||||
<div className="chart-container">
|
||||
{chartTypes.map((type, index) => {
|
||||
const widgetTitle = `Widget ${index + 1}`;
|
||||
return (
|
||||
<ChartWidget
|
||||
key={index}
|
||||
type={type}
|
||||
index={index}
|
||||
title={widgetTitle}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
<ProgressBarWidget
|
||||
id="widget-7"
|
||||
title="Widget 7"
|
||||
data={{
|
||||
stocks: [
|
||||
{ key: "units", value: 1000, description: "Initial stock" },
|
||||
],
|
||||
}}
|
||||
/>
|
||||
<ProgressBarWidget
|
||||
id="widget-8"
|
||||
title="Widget 8"
|
||||
data={{
|
||||
stocks: [
|
||||
{ key: "units", value: 1000, description: "Initial stock" },
|
||||
{ key: "units", value: 500, description: "Additional stock" },
|
||||
],
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Widgets2D;
|
||||
@@ -0,0 +1,30 @@
|
||||
import widget1 from "../../../../../assets/image/3D/ProductionCapacity.png";
|
||||
import widget2 from "../../../../../assets/image/3D/ReturnOfInvestment.png";
|
||||
import widget3 from "../../../../../assets/image/3D/StateWorking.png";
|
||||
import widget4 from "../../../../../assets/image/3D/Throughput.png";
|
||||
const Widgets3D = () => {
|
||||
const widgets = [
|
||||
{ name: "Widget 1", img: widget1 },
|
||||
{ name: "Widget 2", img: widget2 },
|
||||
{ name: "Widget 3", img: widget3 },
|
||||
{ name: "Widget 4", img: widget4 },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="widgets-container widget3D">
|
||||
{widgets?.map((widget, index) => (
|
||||
<div key={index} className="widget-item" draggable>
|
||||
<div className="widget-name">{widget.name}</div>
|
||||
<img
|
||||
className="widget-image"
|
||||
src={widget.img}
|
||||
alt={widget.name}
|
||||
draggable={false}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Widgets3D;
|
||||
@@ -0,0 +1,79 @@
|
||||
import React from "react";
|
||||
import {
|
||||
CartIcon,
|
||||
DocumentIcon,
|
||||
GlobeIcon,
|
||||
WalletIcon,
|
||||
} from "../../../../icons/3dChartIcons";
|
||||
import SimpleCard from "../../../../ui/realTimeVis/floating/SimpleCard";
|
||||
|
||||
import WarehouseThroughput from "../../../../ui/realTimeVis/floating/WarehouseThroughput";
|
||||
import ProductivityDashboard from "../../../../ui/realTimeVis/floating/ProductivityDashboard";
|
||||
import FleetEfficiency from "../../../../ui/realTimeVis/floating/FleetEfficiency";
|
||||
|
||||
interface Widget {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
const WidgetsFloating = () => {
|
||||
// const [widgets, setWidgets] = useState<Widget[]>([
|
||||
// { id: "1", name: "Working State Widget" },
|
||||
// { id: "2", name: "Floating Widget 2" },
|
||||
// { id: "3", name: "Floating Widget 3" },
|
||||
// { id: "4", name: "Floating Widget 4" },
|
||||
// ]);
|
||||
|
||||
// Function to handle drag start
|
||||
const handleDragStart = (
|
||||
e: React.DragEvent<HTMLDivElement>,
|
||||
widget: Widget
|
||||
) => {
|
||||
e.dataTransfer.setData("application/json", JSON.stringify(widget));
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="floatingWidgets-wrapper">
|
||||
{/* {widgets.map((widget) => (
|
||||
<div
|
||||
key={widget.id}
|
||||
className="floating"
|
||||
draggable
|
||||
onDragStart={(e) => handleDragStart(e, widget)}
|
||||
>
|
||||
{widget.name}
|
||||
</div>
|
||||
))} */}
|
||||
{/* Floating 1 */}
|
||||
<SimpleCard
|
||||
header={"Today’s Money"}
|
||||
icon={WalletIcon}
|
||||
value={"$53,000"}
|
||||
per={"+55%"}
|
||||
/>
|
||||
<SimpleCard
|
||||
header={"Today’s Users"}
|
||||
icon={GlobeIcon}
|
||||
value={"1,200"}
|
||||
per={"+30%"}
|
||||
/>
|
||||
<SimpleCard
|
||||
header={"New Clients"}
|
||||
icon={DocumentIcon}
|
||||
value={"250"}
|
||||
per={"+12%"}
|
||||
/>
|
||||
<SimpleCard
|
||||
header={"Total Sales"}
|
||||
icon={CartIcon}
|
||||
value={"$150,000"}
|
||||
per={"+20%"}
|
||||
/>{" "}
|
||||
<WarehouseThroughput />
|
||||
{/* <ProductivityDashboard /> */}
|
||||
<FleetEfficiency />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default WidgetsFloating;
|
||||
Reference in New Issue
Block a user