This commit is contained in:
Vishnu 2025-04-29 18:37:18 +05:30
commit 5460c23a46
15 changed files with 1385 additions and 155 deletions

View File

@ -593,3 +593,212 @@ export const DeleteIcon = () => {
</svg>
);
};
export const HourlySimulationIcon = () => {
return (
<svg
width="17"
height="16"
viewBox="0 0 17 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9.22794 8.29297C9.22794 9.1131 9.69975 9.49575 10.1561 9.86512C10.7275 10.3286 11.371 10.8503 11.4375 12.4462H5.91087C5.97732 10.8503 6.62079 10.3286 7.19228 9.86512C7.64859 9.49575 8.1204 9.1131 8.1204 8.29297C8.1204 7.47284 7.64859 7.09018 7.19228 6.72082C6.62079 6.25732 5.97732 5.73567 5.91087 4.13971H11.4375C11.371 5.73567 10.7275 6.25732 10.1561 6.72082C9.69975 7.09018 9.22794 7.47284 9.22794 8.29297ZM10.5049 7.15054C11.1694 6.61173 11.9968 5.94112 11.9968 3.86282V3.58594H5.35156V3.86282C5.35156 5.94112 6.17889 6.61173 6.84342 7.15054C7.27867 7.50385 7.56663 7.73699 7.56663 8.29297C7.56663 8.84895 7.27867 9.08209 6.84342 9.4354C6.17889 9.97421 5.35156 10.6448 5.35156 12.7231V13H11.9968V12.7231C11.9968 10.6448 11.1695 9.97421 10.5049 9.4354C10.0697 9.08209 9.78171 8.84895 9.78171 8.29297C9.78171 7.73699 10.0697 7.50385 10.5049 7.15054ZM8.54764 9.83582L7.71588 10.5109C7.3515 10.806 7.03751 11.0602 6.86916 11.6156H10.4792C10.3108 11.0602 9.99685 10.806 9.63247 10.5109L8.80071 9.83582C8.72706 9.77602 8.62129 9.77602 8.54764 9.83582Z"
fill="#2B3344"
/>
</svg>
);
};
export const DailyProductionIcon = () => {
return (
<svg
width="17"
height="16"
viewBox="0 0 17 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M13.4564 6.96778C13.3816 6.81906 13.2232 6.72864 13.0596 6.74287L12.5621 6.77922C12.0226 4.82899 10.2365 3.39063 8.11668 3.39063C5.57103 3.39059 3.5 5.46179 3.5 8.00724C3.5 10.5529 5.57103 12.6239 8.11664 12.6239C9.59017 12.6239 10.9876 11.911 11.8549 10.7172C11.988 10.5335 11.947 10.2772 11.7637 10.1437C11.5801 10.0105 11.3235 10.0519 11.1904 10.2347C10.477 11.2167 9.328 11.8032 8.11645 11.8032C6.02331 11.8032 4.32065 10.1003 4.32065 8.00737C4.32065 5.91438 6.02334 4.21163 8.11648 4.21163C9.80226 4.21163 11.2333 5.3171 11.7269 6.84049L11.4679 6.85944C11.3024 6.87139 11.1604 6.98234 11.1083 7.13969C11.0559 7.29735 11.104 7.47084 11.2294 7.57934L11.9746 8.22285C12.0471 8.33961 12.1753 8.41774 12.3224 8.41774C12.3301 8.41774 12.3373 8.41599 12.3449 8.41564C12.3474 8.41564 12.3493 8.4167 12.3516 8.4167C12.3614 8.4167 12.3714 8.41654 12.3816 8.41564C12.4901 8.40757 12.5909 8.35682 12.6622 8.27447L13.3998 7.42041C13.5087 7.2949 13.5308 7.11596 13.4564 6.96778Z"
fill="#2B3344"
/>
<path
d="M5.94531 9.43859V9.04L6.30878 8.71149C6.92314 8.16192 7.22165 7.84585 7.23024 7.51715C7.23024 7.28766 7.09188 7.1061 6.76706 7.1061C6.52494 7.1061 6.31281 7.2269 6.16567 7.33979L5.97956 6.86783C6.19166 6.70822 6.52036 6.57812 6.90122 6.57812C7.53737 6.57812 7.88783 6.95018 7.88783 7.46078C7.88783 7.9324 7.54615 8.30903 7.1393 8.67234L6.87962 8.88866V8.89708H7.9398V9.43823H5.94531V9.43859Z"
fill="#2B3344"
/>
<path
d="M9.51199 9.43788V8.76696H8.26587V8.33889L9.33028 6.625H10.1352V8.27375H10.4726V8.76696H10.1352V9.43788H9.51199ZM9.51199 8.27375V7.65077C9.51199 7.48187 9.52061 7.30909 9.53359 7.12718H9.51638C9.42525 7.30909 9.35168 7.47344 9.25671 7.65077L8.88026 8.26513V8.27375H9.51199Z"
fill="#2B3344"
/>
</svg>
);
};
export const MonthlyROI = () => {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M3.78955 11.9997V4.84175H4.84219V4.21016C4.84221 3.97761 5.03071 3.7891 5.26325 3.7891H6.10535C6.33789 3.7891 6.52639 3.97761 6.52641 4.21012V4.84175H9.47381L9.47379 4.21012C9.47379 3.97756 9.66231 3.78906 9.89485 3.78906H10.737C10.9695 3.78906 11.158 3.97756 11.158 4.21012V4.84175H12.2107V11.9997H3.78955ZM4.42113 11.3681H11.5791V6.52599H4.42113V11.3681ZM4.84219 9.89443H6.10535V10.9471H4.84219V9.89443ZM6.52641 9.89443H7.78957V10.9471H6.52641V9.89443ZM8.21063 9.89443H9.47379V10.9471H8.21063V9.89443ZM9.89485 9.89443H11.158V10.9471H9.89485V9.89443ZM4.84219 8.42073H6.10535V9.47337H4.84219V8.42073ZM6.52641 8.42073H7.78957V9.47337H6.52641V8.42073ZM8.21063 8.42073H9.47379V9.47337H8.21063V8.42073ZM9.89485 8.42073H11.158V9.47337H9.89485V8.42073ZM6.52641 6.94707H7.78957V7.99971H6.52641V6.94707ZM8.21063 6.94707H9.47379V7.99971H8.21063V6.94707ZM9.89485 6.94707H11.158V7.99971H9.89485V6.94707ZM10.2106 4.21019C10.0362 4.21019 9.89485 4.35156 9.89485 4.52598V5.15756C9.89485 5.33198 10.0362 5.47335 10.2106 5.47335H10.4212C10.5956 5.47335 10.737 5.33198 10.737 5.15756V4.52598C10.737 4.35156 10.5956 4.21019 10.4212 4.21019H10.2106ZM5.57904 4.21016C5.40462 4.21016 5.26325 4.35156 5.26325 4.52598V5.15756C5.26325 5.33195 5.40462 5.47335 5.57904 5.47335H5.78956C5.96398 5.47335 6.10535 5.33195 6.10535 5.15756V4.52598C6.10535 4.35156 5.96398 4.21016 5.78956 4.21016H5.57904ZM6.73695 8.63125V9.26285H7.57905V8.63125H6.73695ZM5.05271 8.63125V9.26285H5.89483V8.63125H5.05271ZM8.42117 8.63125V9.26285H9.26327V8.63125H8.42117ZM10.1054 8.63125V9.26283H10.9475V8.63125H10.1054Z"
fill="#2B3344"
/>
</svg>
);
};
export const ExpandIcon = () => {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M16 5.32324C16 5.09668 15.8018 4.89844 15.5752 4.89844H3.96387C3.7373 4.89844 3.53906 5.09668 3.53906 5.32324V6.17285C3.53906 6.39941 3.7373 6.59766 3.96387 6.59766H15.5752C15.8018 6.59766 16 6.39941 16 6.17285V5.32324Z"
fill="#2B3344"
/>
<path
d="M16 13.8232C16 13.5967 15.8018 13.3984 15.5752 13.3984H3.96387C3.7373 13.3984 3.53906 13.5967 3.53906 13.8232V14.6729C3.53906 14.8994 3.7373 15.0977 3.96387 15.0977H15.5752C15.8018 15.0977 16 14.8994 16 14.6729V13.8232Z"
fill="#2B3344"
/>
<path
d="M12.1768 10.8477C12.4033 10.8477 12.6016 10.6494 12.6016 10.4229V9.57324C12.6016 9.34668 12.4033 9.14844 12.1768 9.14844H7.3623C7.13574 9.14844 6.9375 9.34668 6.9375 9.57324V10.4229C6.9375 10.6494 7.13574 10.8477 7.3623 10.8477H12.1768Z"
fill="#2B3344"
/>
</svg>
);
};
export const StartIcon = () => {
return (
<svg
width="21"
height="20"
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.8542 7.58594V10.5918"
stroke="#6F42C1"
strokeWidth="0.901765"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M10.854 15.9971C7.95036 15.9971 5.59375 13.6405 5.59375 10.7369C5.59375 7.83317 7.95036 5.47656 10.854 5.47656C13.7577 5.47656 16.1143 7.83317 16.1143 10.7369"
stroke="#6F42C1"
strokeWidth="0.901765"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M9.05078 3.97656H12.6578"
stroke="#6F42C1"
strokeWidth="0.901765"
strokeMiterlimit="10"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M12.5977 13.898V13.2007C12.5977 12.341 13.2109 11.9863 13.9563 12.4191L14.5575 12.7678L15.1587 13.1165C15.9041 13.5494 15.9041 14.2527 15.1587 14.6856L14.5575 15.0343L13.9563 15.3829C13.2109 15.8158 12.5977 15.4611 12.5977 14.6014V13.898Z"
stroke="#6F42C1"
strokeWidth="0.901765"
strokeMiterlimit="10"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export const EndIcon = () => {
return (
<svg
width="21"
height="20"
viewBox="0 0 21 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M10.8542 7.58594V10.5918"
stroke="#6F42C1"
strokeWidth="0.901765"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M10.854 15.9971C7.95036 15.9971 5.59375 13.6405 5.59375 10.7369C5.59375 7.83317 7.95036 5.47656 10.854 5.47656C13.7577 5.47656 16.1143 7.83317 16.1143 10.7369"
stroke="#6F42C1"
strokeWidth="0.901765"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M9.05078 3.97656H12.6578"
stroke="#6F42C1"
strokeWidth="0.901765"
strokeMiterlimit="10"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M12.5977 13.898V13.2007C12.5977 12.341 13.2109 11.9863 13.9563 12.4191L14.5575 12.7678L15.1587 13.1165C15.9041 13.5494 15.9041 14.2527 15.1587 14.6856L14.5575 15.0343L13.9563 15.3829C13.2109 15.8158 12.5977 15.4611 12.5977 14.6014V13.898Z"
stroke="#6F42C1"
strokeWidth="0.901765"
strokeMiterlimit="10"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export const SpeedIcon = () => {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M9.55992 9.81727L4.10352 6.17969V14.7664L9.55992 11.1288V14.7664L16 10.4731L9.55992 6.17969V9.81727ZM5.1948 12.7273V8.21877L8.57624 10.4731L5.1948 12.7273ZM10.6512 12.7273V8.21877L14.0326 10.4731L10.6512 12.7273Z"
fill="#2B3344"
/>
</svg>
);
};
// export const DublicateIcon = () => {
// return (
// <svg
// width="20"
// height="20"
// viewBox="0 0 20 20"
// fill="none"
// xmlns="http://www.w3.org/2000/svg"
// >
// <path
// fillRule="evenodd"
// clipRule="evenodd"
// d="M14.3125 11.375C14.3125 11.7545 14.0045 12.0625 13.625 12.0625H8.125C7.7455 12.0625 7.4375 11.7545 7.4375 11.375V5.875C7.4375 5.4955 7.7455 5.1875 8.125 5.1875H13.625C14.0045 5.1875 14.3125 5.4955 14.3125 5.875V11.375ZM13.625 4.5H8.125C7.36566 4.5 6.75 5.11566 6.75 5.875V11.375C6.75 12.1343 7.36566 12.75 8.125 12.75H13.625C14.3843 12.75 15 12.1343 15 11.375V5.875C15 5.11566 14.3843 4.5 13.625 4.5ZM11.5625 14.125C11.5625 14.5045 11.2545 14.8125 10.875 14.8125H5.375C4.9955 14.8125 4.6875 14.5045 4.6875 14.125V8.625C4.6875 8.2455 4.9955 7.9375 5.375 7.9375H6.0625V7.25H5.375C4.61566 7.25 4 7.86566 4 8.625V14.125C4 14.8843 4.61566 15.5 5.375 15.5H10.875C11.6343 15.5 12.25 14.8843 12.25 14.125V13.4375H11.5625V14.125Z"
// fill="var(--text-color)"
// />
// </svg>
// );
// };

View File

@ -9,8 +9,8 @@ export function ThroughputSummaryIcon() {
>
<circle cx="13.3457" cy="13.498" r="12.6543" fill="#FC9D2F" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M13.9063 12.9046L14.2265 13.86L14.4378 14.5073C14.9906 16.2239 15.2594 17.2662 15.2594 17.7299C15.2594 18.8219 14.3742 19.7072 13.2822 19.7072C12.1902 19.7072 11.305 18.8219 11.305 17.7299C11.305 17.2106 11.6422 15.9654 12.3379 13.86L12.658 12.9046C12.8604 12.3082 13.704 12.3082 13.9063 12.9046ZM13.2822 7.84375C16.9222 7.84375 19.873 10.7945 19.873 14.4345C19.873 15.7565 19.4823 17.0219 18.7621 18.0974C18.5596 18.3999 18.1502 18.4809 17.8478 18.2784C17.5453 18.0758 17.4643 17.6665 17.6668 17.364C18.2428 16.5038 18.5548 15.4933 18.5548 14.4345C18.5548 11.5225 16.1942 9.16191 13.2822 9.16191C10.3702 9.16191 8.00956 11.5225 8.00956 14.4345C8.00956 15.4933 8.32153 16.5038 8.89752 17.364C9.10005 17.6665 9.01904 18.0758 8.71659 18.2784C8.41414 18.4809 8.00477 18.3999 7.80224 18.0974C7.08206 17.0219 6.69141 15.7565 6.69141 14.4345C6.69141 10.7945 9.6422 7.84375 13.2822 7.84375ZM13.2822 15.2247L13.0657 15.9238L12.9161 16.4319C12.7219 17.111 12.6231 17.5509 12.6231 17.7299C12.6231 18.0939 12.9182 18.389 13.2822 18.389C13.6462 18.389 13.9413 18.0939 13.9413 17.7299C13.9413 17.511 13.7936 16.9022 13.5044 15.9428L13.2822 15.2247Z"
fill="white"
/>
@ -28,8 +28,8 @@ export function ProductionCapacityIcon() {
>
<circle cx="13.3457" cy="13.498" r="12.6543" fill="#FC9D2F" />
<path
fill-rule="evenodd"
clip-rule="evenodd"
fillRule="evenodd"
clipRule="evenodd"
d="M13.9063 12.9046L14.2265 13.86L14.4378 14.5073C14.9906 16.2239 15.2594 17.2662 15.2594 17.7299C15.2594 18.8219 14.3742 19.7072 13.2822 19.7072C12.1902 19.7072 11.305 18.8219 11.305 17.7299C11.305 17.2106 11.6422 15.9654 12.3379 13.86L12.658 12.9046C12.8604 12.3082 13.704 12.3082 13.9063 12.9046ZM13.2822 7.84375C16.9222 7.84375 19.873 10.7945 19.873 14.4345C19.873 15.7565 19.4823 17.0219 18.7621 18.0974C18.5596 18.3999 18.1502 18.4809 17.8478 18.2784C17.5453 18.0758 17.4643 17.6665 17.6668 17.364C18.2428 16.5038 18.5548 15.4933 18.5548 14.4345C18.5548 11.5225 16.1942 9.16191 13.2822 9.16191C10.3702 9.16191 8.00956 11.5225 8.00956 14.4345C8.00956 15.4933 8.32153 16.5038 8.89752 17.364C9.10005 17.6665 9.01904 18.0758 8.71659 18.2784C8.41414 18.4809 8.00477 18.3999 7.80224 18.0974C7.08206 17.0219 6.69141 15.7565 6.69141 14.4345C6.69141 10.7945 9.6422 7.84375 13.2822 7.84375ZM13.2822 15.2247L13.0657 15.9238L12.9161 16.4319C12.7219 17.111 12.6231 17.5509 12.6231 17.7299C12.6231 18.0939 12.9182 18.389 13.2822 18.389C13.6462 18.389 13.9413 18.0939 13.9413 17.7299C13.9413 17.511 13.7936 16.9022 13.5044 15.9428L13.2822 15.2247Z"
fill="white"
/>
@ -49,12 +49,12 @@ export function ROISummaryIcon() {
<path
d="M6.00015 7.51562V19.0974H19.0002"
stroke="white"
stroke-linecap="round"
strokeLinecap="round"
/>
<path
d="M6.50037 15.0553L10.3102 11.847C10.6984 11.52 11.2701 11.5358 11.6397 11.8837L15.0095 15.0553L19.5004 11.2734"
stroke="white"
stroke-linecap="round"
strokeLinecap="round"
/>
</svg>
);

View File

@ -1,10 +1,14 @@
import React from "react";
import React, { useState } from "react";
import { ProductionCapacityIcon } from "../../icons/analysis";
const ProductionCapacity = () => {
const ProductionCapacity = ({
progressPercent = 10,
avgProcessTime = "28.4 Secs/unit",
machineUtilization = "78%",
throughputValue = 128,
timeRange = { startTime: "08:00 AM", endTime: "09:00 AM" },
}) => {
const totalBars = 6;
const progressPercent = 50;
const barsToFill = Math.floor((progressPercent / 100) * totalBars);
const partialFillPercent =
((progressPercent / 100) * totalBars - barsToFill) * 100;
@ -14,8 +18,10 @@ const ProductionCapacity = () => {
<div className="productionCapacity-wrapper analysis-card-wrapper">
<div className="card-header">
<div className="header">
<div className="main-header">Throughput Summary</div>
<div className="sub-header">08:00 - 09:00 AM</div>
<div className="main-header">Production Capacity</div>
<div className="sub-header">
{timeRange.startTime} - {timeRange.endTime}
</div>
</div>
<div className="icon-wrapper">
<ProductionCapacityIcon />
@ -24,10 +30,10 @@ const ProductionCapacity = () => {
<div className="process-container">
<div className="throughput-value">
<span className="value">128</span> Units/hour
<span className="value">{throughputValue}</span> Units/hour
</div>
{/* Progress Bar */}
{/* Dynamic Progress Bar */}
<div className="progress-bar-wrapper">
{[...Array(totalBars)].map((_, i) => (
<div className="progress-bar" key={i}>
@ -47,11 +53,11 @@ const ProductionCapacity = () => {
<div className="metrics-section">
<div className="metric">
<span className="label">Avg. Process Time</span>
<span className="value">28.4 Secs/unit</span>
<span className="value">{avgProcessTime}</span>
</div>
<div className="metric">
<span className="label">Machine Utilization</span>
<span className="value">78%</span>
<span className="value">{machineUtilization}</span>
</div>
</div>
</div>

View File

@ -1,10 +1,71 @@
import React from "react";
import React, { useState } from "react";
import { ROISummaryIcon } from "../../icons/analysis";
import SemiCircleProgress from "./SemiCircleProgress";
const ROISummary = ({
roiSummaryData = {
productName: "Product name",
roiPercentage: 133,
paybackPeriod: 50.3,
totalCost: "₹ 1,20,000",
revenueGenerated: "₹ 2,80,000",
netProfit: "₹ 1,60,000",
costBreakdown: [
{
item: "Raw Material A",
unitCost: "₹ 10/unit",
laborCost: "₹ 0",
totalCost: "₹ 1000",
sellingPrice: "₹ 1500",
},
{
item: "Labor",
unitCost: "₹ 10/unit",
laborCost: "₹ 500",
totalCost: "₹ 500",
sellingPrice: "N/A",
},
{
item: "Product 1",
unitCost: "₹ 10/unit",
laborCost: "₹ 200",
totalCost: "₹ 200",
sellingPrice: "₹ 2000",
},
{
item: "Machine",
unitCost: "-",
laborCost: "-",
totalCost: "₹ 20,000",
sellingPrice: "N/A",
},
{
item: "Total",
unitCost: "-",
laborCost: "-",
totalCost: "₹ 1,20,000",
sellingPrice: "-",
},
{
item: "Net Profit",
unitCost: "-",
laborCost: "-",
totalCost: "₹ 1,60,000",
sellingPrice: "-",
},
],
},
}) => {
const [isTableOpen, setIsTableOpen] = useState(false); // State to handle the table open/close
// Function to toggle the breakdown table visibility
const toggleTable = () => {
setIsTableOpen(!isTableOpen);
};
const ROISummary = () => {
return (
<div className="analysis-card">
<div className="throughoutSummary-wrapper analysis-card-wrapper">
<div className="roiSummary-container analysis-card">
<div className="roiSummary-wrapper analysis-card-wrapper">
<div className="card-header">
<div className="header">
<div className="main-header">ROI Summary</div>
@ -14,6 +75,111 @@ const ROISummary = () => {
<ROISummaryIcon />
</div>
</div>
<div className="product-info">
<div className="product-label">Product :</div>
<div className="product-name">{roiSummaryData.productName}</div>
</div>
<div className="playBack">
<div className="icon"></div>
<div className="info">
<span>+{roiSummaryData.roiPercentage}%</span> ROI with payback in
just <span>{roiSummaryData.paybackPeriod}</span> months
</div>
</div>
<div className="roi-details">
<div className="progress-wrapper">
<SemiCircleProgress />
<div className="content">
you're on track to hit it by
<div className="key">July 2029</div>
</div>
</div>
<div className="metrics">
<div className="metric-wrapper">
<div className="metric-item">
<span className="metric-label">Total Cost Incurred</span>
<span className="metric-value">{roiSummaryData.totalCost}</span>
</div>
<div className="metric-item">
<span className="metric-label">Revenue Generated</span>
<span className="metric-value">
{roiSummaryData.revenueGenerated}
</span>
</div>
</div>
<div className="metric-item net-profit">
<span className="metric-label">Net Profit</span>
<span className="metric-value">{roiSummaryData.netProfit}</span>
</div>
</div>
</div>
<div className="cost-breakdown">
<div className="breakdown-header" onClick={toggleTable}>
<div className="section-wrapper">
<span className="section-number"></span>
<span className="section-title">Cost Breakdown</span>
</div>
<span className={`expand-icon ${isTableOpen ? "open" : ""}`}>
{isTableOpen ? "⌵" : "⌵"}
</span>
</div>
<div
className={`breakdown-table-wrapper ${
isTableOpen ? "open" : "closed"
}`}
style={{
transition: "max-height 0.3s ease-in-out",
overflow: "hidden",
}}
>
<table className="breakdown-table">
<thead>
<tr>
<th>Item</th>
<th>Unit Cost</th>
<th>Labor Cost</th>
<th>Total Cost</th>
<th>Selling Price</th>
</tr>
</thead>
<tbody>
{roiSummaryData.costBreakdown.map((row, index) => (
<tr
key={index}
className={
row.item === "Total"
? "total-row"
: row.item === "Net Profit"
? "net-profit-row"
: ""
}
>
<td>{row.item}</td>
<td>{row.unitCost}</td>
<td>{row.laborCost}</td>
<td>{row.totalCost}</td>
<td>{row.sellingPrice}</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
<div className="tips-section">
<div className="tip-header">
<span className="lightbulb-icon">💡</span>
<span className="tip-title">How to improve ROI?</span>
</div>
<div className="tip-description">
Increase CNC utilization by <span className="highlight">10%</span>{" "}
to shave <span className="highlight">0.5</span> months of payback
period
</div>
<button className="get-tips-button">
<div className="btn">Get ROI Boost Tips</div>
</button>
</div>
</div>
</div>
);

View File

@ -0,0 +1,27 @@
import React from "react";
const SemiCircleProgress = () => {
const progress = 50;
const clampedProgress = Math.min(Math.max(progress, 0), 100);
const gradientProgress = clampedProgress * 0.5;
return (
<div className="semi-circle-wrapper">
<div
className="semi-circle"
style={{
background: `conic-gradient(from 270deg, skyblue 0% ${gradientProgress}%, lightgray ${gradientProgress}% 100%)`,
}}
>
<div className="progress-cover"></div>
</div>
<div className="label-wrapper">
<div className="label">{clampedProgress}%</div>
<div className="label-content">Years</div>
</div>
<div className="content">you're on track to hit it by July 2029</div>
</div>
);
};
export default SemiCircleProgress;

View File

@ -11,21 +11,57 @@ import { PowerIcon, ThroughputSummaryIcon } from "../../icons/analysis";
ChartJS.register(LineElement, CategoryScale, LinearScale, PointElement);
// Helper function to generate random colors
const getRandomColor = () => {
const letters = "0123456789ABCDEF";
let color = "#";
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
const ThroughputSummary = () => {
const data = {
// Define all data internally within the component
const timeRange = {
startTime: "08:00 AM",
endTime: "09:00 AM",
};
const throughputData = {
labels: ["08:00", "08:10", "08:20", "08:30", "08:40", "08:50", "09:00"],
data: [100, 120, 110, 130, 125, 128, 132],
totalThroughput: 1240,
assetUsage: 85,
};
const energyConsumption = {
energyConsumed: 456,
unit: "KWH",
};
// Dynamic shift data
const shiftUtilization = [
{ shift: 1, percentage: 30 },
{ shift: 2, percentage: 40 },
{ shift: 3, percentage: 30 },
];
// Chart data configuration
const chartData = {
labels: throughputData.labels,
datasets: [
{
label: "Units/hour",
data: [100, 120, 110, 130, 125, 128, 132],
data: throughputData.data,
borderColor: "#B392F0",
tension: 0.4,
pointRadius: 0, // hide points
pointRadius: 0, // Hide points
},
],
};
const options = {
const chartOptions = {
responsive: true,
scales: {
x: {
@ -57,19 +93,15 @@ const ThroughputSummary = () => {
},
};
const shiftUtilization = {
"shift 1": 25,
"shift 2": 45,
"shift 3": 15,
};
return (
<div className="throughoutSummary analysis-card">
<div className="throughoutSummary-wrapper analysis-card-wrapper">
<div className="card-header">
<div className="header">
<div className="main-header">Throughput Summary</div>
<div className="sub-header">08:00 - 09:00 AM</div>
<div className="sub-header">
{timeRange.startTime} - {timeRange.endTime}
</div>
</div>
<div className="icon-wrapper">
<ThroughputSummaryIcon />
@ -78,14 +110,15 @@ const ThroughputSummary = () => {
<div className="process-container">
<div className="throughput-value">
<span className="value">1240</span> Units/hour
<span className="value">{throughputData.totalThroughput}</span>{" "}
Units/hour
</div>
<div className="lineChart">
<div className="assetUsage">
<div className="key">Asset usage</div>
<div className="value">85%</div>
<div className="value">{throughputData.assetUsage}%</div>
</div>
<Line data={data} options={options} />
<Line data={chartData} options={chartOptions} />
</div>
</div>
@ -97,43 +130,41 @@ const ThroughputSummary = () => {
<PowerIcon />
</div>
<div className="value-wrapper">
<div className="value">456</div>
<div className="unit">KWH</div>
<div className="value">{energyConsumption.energyConsumed}</div>
<div className="unit">{energyConsumption.unit}</div>
</div>
</div>
</div>
<div className="shiftUtilization footer-card">
<div className="header">Shift Utilization</div>
<div className="value-container">
<div className="value">85%</div>
<div className="value">{throughputData.assetUsage}%</div>
<div className="progress-wrapper">
{/* Dynamically create progress bars based on shiftUtilization array */}
{shiftUtilization.map((shift) => (
<div
className="progress shift-1"
style={{ width: "30%" }}
></div>
<div
className="progress shift-2"
style={{ width: "40%" }}
></div>
<div
className="progress shift-3"
style={{ width: "30%" }}
key={shift.shift}
className={`progress shift-${shift.shift}`}
style={{
width: `${shift.percentage}%`,
backgroundColor: getRandomColor(),
}}
></div>
))}
</div>
<div className="progress-indicator">
<div className="shift-wrapper">
<span className="indicator shift-1"></span>
<label>Shift 1</label>
</div>
<div className="shift-wrapper">
<span className="indicator shift-2"></span>
<label>Shift 2</label>
</div>
<div className="shift-wrapper">
<span className="indicator shift-3"></span>
<label>Shift 3</label>
{/* Dynamically create shift indicators with random colors */}
{shiftUtilization.map((shift) => (
<div className="shift-wrapper" key={shift.shift}>
<span
className={`indicator shift-${shift.shift}`}
style={{ backgroundColor: getRandomColor() }} // Random color for indicator
></span>
<label>Shift {shift.shift}</label>
</div>
))}
</div>
</div>
</div>

View File

@ -7,6 +7,15 @@ import {
usePlayButtonStore,
useResetButtonStore,
} from "../../../store/usePlayButtonStore";
import {
DailyProductionIcon,
EndIcon,
ExpandIcon,
HourlySimulationIcon,
MonthlyROI,
SpeedIcon,
StartIcon,
} from "../../icons/ExportCommonIcons";
const SimulationPlayer: React.FC = () => {
const { speed, setSpeed } = useAnimationPlaySpeed();
@ -30,7 +39,7 @@ const SimulationPlayer: React.FC = () => {
const handleExit = () => {
setPlaySimulation(false);
setIsPlaying(false);
setActiveTool("cursor")
setActiveTool("cursor");
};
// Slider functions starts
@ -72,10 +81,128 @@ const SimulationPlayer: React.FC = () => {
}, []);
// Slider function ends
// UI-Part
const hourlySimulation = 25;
const dailyProduction = 75;
const monthlyROI = 50;
const process = [
{ name: "process 1", completed: 0 }, // 0% completed
{ name: "process 2", completed: 20 }, // 20% completed
{ name: "process 3", completed: 40 }, // 40% completed
{ name: "process 4", completed: 60 }, // 60% completed
{ name: "process 5", completed: 80 }, // 80% completed
{ name: "process 6", completed: 100 }, // 100% completed
{ name: "process 7", completed: 0 }, // 0% completed
{ name: "process 8", completed: 50 }, // 50% completed
{ name: "process 9", completed: 90 }, // 90% completed
{ name: "process 10", completed: 30 }, // 30% completed
];
const [expand, setExpand] = useState(false);
// Move getRandomColor out of render
const getRandomColor = () => {
const letters = "0123456789ABCDEF";
let color = "#";
for (let i = 0; i < 6; i++) {
color += letters[Math.floor(Math.random() * 16)];
}
return color;
};
// Store colors for each process item
const [processColors, setProcessColors] = useState<string[]>([]);
// Generate colors on mount or when process changes
useEffect(() => {
const generatedColors = process.map(() => getRandomColor());
setProcessColors(generatedColors);
}, []);
const intervals = [10, 20, 30, 40, 50, 60]; // in minutes
const totalSegments = intervals.length;
const progress = 80; // percent (example)
const processPlayerRef = useRef<HTMLDivElement>(null);
const processWrapperRef = useRef<HTMLDivElement>(null);
const [playerPosition, setPlayerPosition] = useState(0);
const handleProcessMouseDown = (e: React.MouseEvent) => {
if (!processWrapperRef.current) return;
const rect = processWrapperRef.current.getBoundingClientRect();
let x = e.clientX - rect.left;
x = Math.max(0, Math.min(x, rect.width));
setPlayerPosition(x);
const onMouseMove = (e: MouseEvent) => {
if (!processWrapperRef.current) return;
const newRect = processWrapperRef.current.getBoundingClientRect();
let newX = e.clientX - newRect.left;
newX = Math.max(0, Math.min(newX, newRect.width));
setPlayerPosition(newX);
const progressPercent = (newX / newRect.width) * 100;
console.log(`Dragging at progress: ${progressPercent.toFixed(1)}%`);
};
const onMouseUp = () => {
document.removeEventListener("mousemove", onMouseMove);
document.removeEventListener("mouseup", onMouseUp);
};
document.addEventListener("mousemove", onMouseMove);
document.addEventListener("mouseup", onMouseUp);
};
return (
<div className="simulation-player-wrapper">
<div className="simulation-player-container">
<div className={`simulation-player-container ${expand ? "open" : ""}`}>
<div className="controls-container">
<div className="production-details">
{/* hourlySimulation */}
<div className="hourly-wrapper production-wrapper">
<div className="header">
<div className="icon">
<HourlySimulationIcon />
</div>
<div className="label">Hourly Simulation</div>
</div>
<div className="progress-wrapper">
<div
className="progress"
style={{ width: hourlySimulation }}
></div>
</div>
</div>
{/* dailyProduction */}
<div className="dailyProduction-wrapper production-wrapper">
<div className="header">
<div className="icon">
<DailyProductionIcon />
</div>
<div className="label">Daily Production</div>
</div>
<div className="progress-wrapper">
<div
className="progress"
style={{ width: dailyProduction }}
></div>
</div>
</div>
{/* monthlyROI */}
<div className="monthlyROI-wrapper production-wrapper">
<div className="header">
<div className="icon">
<MonthlyROI />
</div>
<div className="label">Monthly ROI</div>
</div>
<div className="progress-wrapper">
<div className="progress" style={{ width: monthlyROI }}></div>
</div>{" "}
</div>
</div>
<div className="controls-wrapper">
<div
className="simulation-button-container"
onClick={() => {
@ -103,10 +230,71 @@ const SimulationPlayer: React.FC = () => {
<ExitIcon />
Exit
</div>
<div
className="simulation-button-container"
onClick={() => setExpand(!expand)}
>
<ExpandIcon />
</div>
</div>
</div>
<div className="progresser-wrapper">
<div className="time-displayer">
<div className="start-time-wrappper">
<div className="icon">
<StartIcon />
</div>
<div className="time-wrapper">
<div className="date">23 April ,25</div>
<div className="time">04:41 PM</div>
</div>
</div>
<div className="time-progresser">
<div className="timeline">
{intervals.map((label, index) => {
const segmentProgress = (index / totalSegments) * 100;
const isFilled = progress >= segmentProgress;
return (
<React.Fragment key={index}>
<div className="label-dot-wrapper">
<div className="label">{label} mins</div>
<div
className={`dot ${isFilled ? "filled" : ""}`}
></div>
</div>
{index < intervals.length - 1 && (
<div
className={`line ${
progress >= ((index + 1) / totalSegments) * 100
? "filled"
: ""
}`}
></div>
)}
</React.Fragment>
);
})}
</div>
</div>
<div className="end-time-wrappper">
<div className="time-wrapper">
<div className="time">00:10:20</div>
</div>
<div className="icon">
<EndIcon />
</div>
</div>
</div>
<div className="speed-control-container">
<div className="min-value">0.5x</div>
<div className="min-value">
<div className="icon">
<SpeedIcon />
</div>
Speed
</div>
<div className="slider-container" ref={sliderRef}>
<div className="speed-label mix-value">0X</div>
<div className="marker marker-10"></div>
<div className="marker marker-20"></div>
<div className="marker marker-30"></div>
@ -134,8 +322,36 @@ const SimulationPlayer: React.FC = () => {
className="slider-input"
/>
</div>
<div className="speed-label max-value">8x</div>
</div>
<div className="max-value">8x</div>
</div>
</div>
<div className="processDisplayer">
<div
className="process-player"
style={{ left: playerPosition, position: "absolute" }}
></div>
<div
className="process-wrapper"
ref={processWrapperRef}
onMouseDown={handleProcessMouseDown}
>
{process.map((item, index) => (
<div
key={index}
className="process"
style={{
width: `${item.completed}%`,
backgroundColor: processColors[index],
}}
></div>
))}
</div>
<div
className="process-player"
ref={processPlayerRef}
style={{ left: playerPosition, position: "absolute" }}
></div>
</div>
</div>
</div>

View File

@ -335,7 +335,7 @@ const RealTimeVisulization: React.FC = () => {
onDrop={(event) => handleDrop(event)}
onDragOver={(event) => event.preventDefault()}
>
<Scene />
{/* <Scene /> */}
</div>
{activeModule === "visualization" && selectedZone.zoneName !== "" && (
<DroppedObjects />

View File

@ -64,7 +64,7 @@ const Project: React.FC = () => {
<ROISummary />
</div> */}
<KeyPressListener />
{loadingProgress && <LoadingPage progress={loadingProgress} />}
{/* {loadingProgress && <LoadingPage progress={loadingProgress} />} */}
{!isPlaying && (
<>
{toggleThreeD && <ModuleToggle />}

View File

@ -0,0 +1,318 @@
.roiSummary-container {
.roiSummary-wrapper {
background-color: var(--background-color);
.product-info {
display: flex;
}
.playBack {
display: flex;
background-color: var(--background-color);
border-radius: 12px;
padding: 6px;
.info {
span {
font-size: var(--font-size-xlarge);
&:first-child {
color: #31C756;
}
&:last-child {
color: var(--text-color);
}
}
}
}
.roi-details {
display: flex;
align-items: center;
gap: 12px;
.progress-wrapper {
width: 250px;
display: flex;
flex-direction: column;
gap: 6px;
.content {
display: flex;
flex-direction: column;
gap: 3px;
align-items: center;
.key {
font-size: var(--font-size-xlarge);
color: var(--accent-color);
}
}
}
.roi-progress {
width: 100%;
}
.metrics {
display: flex;
flex-direction: column;
gap: 6px;
.metric-item {
width: 100%;
border-radius: 6px;
border: 1px solid #00FF56;
background: #436D51;
display: flex;
flex-direction: column;
padding: 4px 6px;
&:last-child {
align-items: center;
}
.metric-label {
font-size: 10px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.metric-value {
text-align: center;
line-height: 20px;
}
}
.metric-wrapper {
display: flex;
gap: 6px;
.metric-item {
background-color: var(--background-color);
border: 1px solid var(--Grays-Gray-6, #F2F2F7);
}
}
}
}
.cost-breakdown {
background-color: var(--background-color);
border: 1px solid var(--text-disabled);
border-radius: 8px;
padding: 16px;
.breakdown-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-bottom: 16px;
.section-wrapper {
display: flex;
gap: 4px;
align-items: center;
}
.section-number {
font-size: 20px;
color: #00aaff;
}
.section-title {
font-size: var(--font-size-regular);
color: var(--text-color);
}
.expand-icon {
font-size: 16px;
color: var(--text-color);
cursor: pointer;
transform: rotate(90deg);
transition: transform 0.2s linear;
}
.expand-icon.open {
transform: rotate(0deg);
}
}
.breakdown-table {
width: 100%;
border-collapse: collapse;
border-radius: 8px;
th,
td {
padding: 8px;
text-align: left;
border-top: 1px solid var(--text-disabled);
border-bottom: 1px solid var(--text-disabled);
}
th:first-child,
td:first-child {
border-left: 1px solid var(--text-disabled);
}
th:last-child,
td:last-child {
border-right: 1px solid var(--text-disabled);
}
th {
background-color: var(--background-color);
color: #333;
}
.total-row,
.net-profit-row {
font-weight: bold;
color: #333;
}
}
}
.tips-section {
background-color: var(--background-color);
border-radius: 8px;
display: flex;
flex-direction: column;
gap: 6px;
padding: 12px;
.tip-header {
display: flex;
align-items: center;
.tip-title {
color: var(--text-color);
font-weight: 600;
}
}
.tip-description {
span {
font-size: var(--font-size-xlarge);
color: #34C759;
&:first-child {
color: #34C759;
}
&:nth-child(2) {
color: #488EF6;
}
}
}
}
.get-tips-button {
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
margin-top: 8px;
display: inline-block;
display: flex;
justify-content: flex-end;
background: none;
.btn {
background-color: var(--accent-color);
color: var(--background-color);
padding: 4px 6px;
border-radius: 5px;
display: inline-block;
font-size: 14px;
text-align: center;
}
}
}
.semi-circle-wrapper {
width: 100%;
height: 125px;
overflow-y: hidden;
position: relative;
}
.semi-circle {
width: 100%;
height: 250px;
border-radius: 50%;
position: relative;
transition: background 0.5s ease;
}
.progress-cover {
position: absolute;
width: 75%;
height: 75%;
top: 12.5%;
left: 12.5%;
background-color: var(--background-color);
border-radius: 50%;
}
.label-wrapper {
.label {
font-size: var(--font-size-xxxlarge);
}
position: absolute;
bottom: 0%;
left: 50%;
transform: translate(-50%, 0%);
font-weight: bold;
font-size: 1.2rem;
color: #333;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
}
// Breakdown Table Open/Close Logic
.breakdown-table-wrapper {
&.closed {
max-height: 0;
padding: 0;
}
&.open {
max-height: 500px;
}
.breakdown-table {
width: 100%;
border-collapse: collapse;
th,
td {
padding: 10px;
border: 1px solid #ddd;
text-align: left;
}
.total-row {
background-color: #f4f4f4;
font-weight: bold;
}
.net-profit-row {
background-color: #dff0d8;
font-weight: bold;
}
}
}

View File

@ -1,18 +1,25 @@
.analysis {
position: absolute;
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
justify-content: space-between;
align-items: start;
width: 100%;
height: 100vh;
z-index: 100000000000000000000000000000;
// pointer-events: none;k
z-index: 10000;
.analysis-wrapper {
display: flex;
flex-direction: column;
gap: 12px;
}
}
.analysis-card {
min-width: 333px;
// background: var(--primary-color);
background: var(--background-color);
border-radius: 20px;
padding: 8px;

View File

@ -3,15 +3,75 @@
.simulation-player-wrapper {
position: fixed;
bottom: 32px;
bottom: 50px;
left: 50%;
z-index: 2;
transform: translate(-50%, 0);
width: 70%;
.simulation-player-container {
background-color: var(--background-color);
padding: 7px;
border-radius: 15px;
display: flex;
flex-direction: column;
gap: 8px;
.progresser-wrapper {
background-color: var(--highlight-accent-color);
padding: 4px 5px;
border-radius: 12px;
display: flex;
flex-direction: column;
gap: 12px;
padding-top: 30px;
transition: height 0.2s linear;
}
.controls-container {
@include flex-center;
gap: 12px;
margin-bottom: 4px;
justify-content: space-between;
.production-details,
.controls-wrapper {
display: flex;
gap: 6px;
}
.production-details {
.production-wrapper {
display: flex;
align-items: center;
flex-direction: column;
gap: 6px;
.header {
display: flex;
flex-direction: row;
gap: 6px
}
.progress-wrapper {
width: 164px;
height: 8px;
border-radius: 5px;
// overflow: hidden;
background-color: var(--highlight-accent-color);
.progress {
border-radius: 5px;
height: 100%;
background-color: var(--accent-color);
}
}
}
}
.simulation-button-container {
@include flex-center;
gap: 2px;
@ -20,38 +80,74 @@
background: var(--background-color);
border-radius: #{$border-radius-small};
cursor: pointer;
&:hover {
background: var(--highlight-accent-color);
color: var(--accent-color);
path {
stroke: var(--accent-color);
}
}
}
}
.speed-control-container {
@include flex-center;
gap: 18px;
padding: 5px 16px;
background: var(--background-color);
// background: var(--background-color);
border-radius: #{$border-radius-medium};
box-sizing: #{$box-shadow-medium};
border-radius: 20px;
position: relative;
.min-value,
.max-value {
display: flex;
align-items: center;
font-weight: var(--font-weight-bold);
}
.slider-container {
width: 580px;
width: 100%;
max-width: 80vw;
height: 28px;
background: var(--background-color-gray);
// background: var(--background-color-gray);
border-radius: #{$border-radius-small};
position: relative;
padding: 4px 26px;
// padding: 4px 26px;
.speed-label {
font-size: var(--font-size-tiny);
position: absolute;
bottom: -4px;
&:first-child {
left: 0;
}
&:last-child {
right: 0;
}
}
&::after {
content: "";
background-color: #E5E5EA;
position: absolute;
top: 50%;
transform: translate(0, -50%);
width: 100%;
height: 3px;
}
.custom-slider {
height: 100%;
width: 100%;
position: relative;
.slider-input {
position: absolute;
width: 100%;
@ -60,55 +156,207 @@
z-index: 3;
cursor: pointer;
}
.slider-handle {
position: absolute;
top: 50%;
width: 42px;
line-height: 20px;
text-align: center;
background: var(--accent-color);
color: var(--primary-color);
border-radius: #{$border-radius-small};
transform: translateX(-50%);
transform: translate(-50%, -50%);
cursor: pointer;
z-index: 2;
}
}
.marker{
position: absolute;
background: var(--text-disabled);
background-color: var(--text-disabled);
width: 2px;
height: 12px;
border-radius: 1px;
top: 8px;
}
.marker.marker-10 {
left: 10%;
}
.marker.marker-20 {
left: 20%;
}
.marker.marker-30 {
left: 30%;
}
.marker.marker-40 {
left: 40%;
}
.marker.marker-50 {
left: 50%;
}
.marker.marker-60 {
left: 60%;
}
.marker.marker-70 {
left: 70%;
}
.marker.marker-80 {
left: 80%;
}
.marker.marker-90 {
left: 90%;
}
}
}
.time-displayer {
display: flex;
justify-content: space-between;
height: auto;
opacity: 1;
// overflow: hidden;
transition: all 0.5s ease;
.start-time-wrappper,
.end-time-wrappper {
display: flex;
align-items: center;
gap: 12px;
}
.time-progresser {
width: 70%;
.timeline {
padding: 16px;
// background: #f5f3fa;
background: linear-gradient(90.17deg, rgba(255, 255, 255, 0.64) 1.53%, rgba(255, 255, 255, 0.48) 98.13%);
border-radius: 30px;
display: flex;
align-items: center;
width: 100%;
height: 33px;
.label-dot-wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
position: relative;
.label {
position: absolute;
top: -200%;
transform: translate(0, -0);
font-size: 12px;
color: #666;
white-space: nowrap;
}
.dot {
width: 14px;
height: 14px;
border-radius: 50%;
background-color: #d3d3e2;
&.filled {
background-color: #8f5cf2;
border: 4px solid var(--accent-color);
}
}
}
.line {
flex-grow: 1;
height: 4px;
background-color: #d3d3e2;
margin: 0 4px;
&.filled {
background-color: #8f5cf2;
}
}
}
}
}
}
}
.processDisplayer {
border-radius: 5px;
// overflow: hidden;
background-color: var(--highlight-accent-color);
padding: 14px 6px;
position: relative;
.process-player {
position: absolute;
top: 50%;
transform: translate(0, -50%);
width: 3.946108102798462px;
height: 26px;
left: 86.81px;
border-radius: 14px;
border-width: 1px;
background: var(--accent-color, #6F42C1);
}
.process-wrapper {
display: flex;
// padding: 0px 16px;
.process {
height: 5px;
background-color: #4caf50;
color: white;
text-align: center;
line-height: 30px;
transition: width 0.3s ease;
}
}
}
.simulation-player-container.open {
.progresser-wrapper {
padding-top: 4px;
}
.time-displayer {
height: 0;
opacity: 0;
pointer-events: none;
display: none;
}
.processDisplayer {
padding: 0;
background: transparent;
.process-player {
width: 0;
display: none !important;
}
}
}

View File

@ -434,7 +434,7 @@
button {
path {
stroke: var(--accent-color);
stroke-width: 1.5px;
strokeWidth: 1.5px;
}
color: var(--accent-color);
&:before {
@ -713,7 +713,7 @@
path {
stroke: var(--accent-color);
stroke-width: 1.5px;
strokeWidth: 1.5px;
}
&:hover {

View File

@ -26,6 +26,7 @@
@use 'components/menu/menu';
@use 'components/confirmationPopUp';
@use 'components/analysis/analysis';
@use 'components/analysis/ROISummary.scss';
// layout
@use 'layout/loading';

View File

@ -662,6 +662,7 @@
}
.distance-line {
position: absolute;
border-style: dashed;
border-color: var(--accent-color);