Merge remote-tracking branch 'origin/realTimeVisulization' into simulation
This commit is contained in:
commit
a5cdd53568
2
app/.env
2
app/.env
|
@ -7,6 +7,8 @@ REACT_APP_SERVER_SOCKET_API_BASE_URL=185.100.212.76:8000
|
|||
# Base URL for the server REST API, used for HTTP requests to the backend server.
|
||||
REACT_APP_SERVER_REST_API_BASE_URL=185.100.212.76:5000
|
||||
|
||||
REACT_APP_SERVER_REST_API_LOCAL_BASE_URL=192.168.0.102:5000
|
||||
|
||||
# Base URL for the server marketplace API.
|
||||
# REACT_APP_SERVER_MARKETPLACE_URL=185.100.212.76:50011
|
||||
REACT_APP_SERVER_MARKETPLACE_URL=192.168.0.111:3501
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
"@types/react-dom": "^18.3.0",
|
||||
"@use-gesture/react": "^10.3.1",
|
||||
"chart.js": "^4.4.8",
|
||||
"chartjs-plugin-annotation": "^3.1.0",
|
||||
"glob": "^11.0.0",
|
||||
"gsap": "^3.12.5",
|
||||
"leva": "^0.10.0",
|
||||
|
@ -8499,6 +8500,15 @@
|
|||
"pnpm": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/chartjs-plugin-annotation": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/chartjs-plugin-annotation/-/chartjs-plugin-annotation-3.1.0.tgz",
|
||||
"integrity": "sha512-EkAed6/ycXD/7n0ShrlT1T2Hm3acnbFhgkIEJLa0X+M6S16x0zwj1Fv4suv/2bwayCT3jGPdAtI9uLcAMToaQQ==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"chart.js": ">=4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/check-more-types": {
|
||||
"version": "2.24.0",
|
||||
"resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz",
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
"@types/react-dom": "^18.3.0",
|
||||
"@use-gesture/react": "^10.3.1",
|
||||
"chart.js": "^4.4.8",
|
||||
"chartjs-plugin-annotation": "^3.1.0",
|
||||
"glob": "^11.0.0",
|
||||
"gsap": "^3.12.5",
|
||||
"leva": "^0.10.0",
|
||||
|
|
|
@ -1,255 +1,255 @@
|
|||
export function NotificationIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10 12.8335C10 13.3639 9.78927 13.8726 9.4142 14.2477C9.03913 14.6228 8.5304 14.8335 8 14.8335C7.4696 14.8335 6.96087 14.6228 6.58579 14.2477C6.21072 13.8726 6 13.3639 6 12.8335"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M3.72064 12.1667C3.39434 12.0974 3.10586 11.9084 2.91209 11.6369C2.71832 11.3653 2.63337 11.0311 2.67399 10.7L3.34066 5.29332C3.51087 4.18175 4.07672 3.16901 4.93414 2.44143C5.79156 1.71384 6.88287 1.32036 8.00734 1.33332C9.1318 1.32036 10.2231 1.71384 11.0805 2.44143C11.9379 3.16901 12.5038 4.18175 12.674 5.29332L13.3407 10.7C13.3815 11.0301 13.2975 11.3636 13.1051 11.635C12.9127 11.9063 12.6257 12.096 12.3007 12.1667C9.47907 12.8297 6.54222 12.8297 3.72064 12.1667Z"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function HomeIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6.91304 13.5V12.8333C6.91304 12.281 7.36076 11.8333 7.91304 11.8333H8.95652C9.50881 11.8333 9.95652 12.281 9.95652 12.8333V13.5C9.95652 14.0523 10.4042 14.5 10.9565 14.5H12C12.5523 14.5 13 14.0523 13 13.5V7.38889L8.21739 2.5L3 7.38889V13.5C3 14.0523 3.44772 14.5 4 14.5H5.91304C6.46533 14.5 6.91304 14.0523 6.91304 13.5Z"
|
||||
stroke="var(--text-color)"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function ProjectsIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12.1538 1.5H5.69231C5.20268 1.5 4.7331 1.68437 4.38688 2.01256C4.04066 2.34075 3.84615 2.78587 3.84615 3.25C3.35652 3.25 2.88695 3.43437 2.54073 3.76256C2.1945 4.09075 2 4.53587 2 5V13.75C2 14.2141 2.1945 14.6592 2.54073 14.9874C2.88695 15.3156 3.35652 15.5 3.84615 15.5H10.3077C10.7973 15.5 11.2669 15.3156 11.6131 14.9874C11.9593 14.6592 12.1538 14.2141 12.1538 13.75C12.6435 13.75 13.1131 13.5656 13.4593 13.2374C13.8055 12.9092 14 12.4641 14 12V3.25C14 2.78587 13.8055 2.34075 13.4593 2.01256C13.1131 1.68437 12.6435 1.5 12.1538 1.5ZM12.1538 12.875V5C12.1538 4.53587 11.9593 4.09075 11.6131 3.76256C11.2669 3.43437 10.7973 3.25 10.3077 3.25H4.76923C4.76923 3.01794 4.86648 2.79538 5.03959 2.63128C5.2127 2.46719 5.44749 2.375 5.69231 2.375H12.1538C12.3987 2.375 12.6334 2.46719 12.8066 2.63128C12.9797 2.79538 13.0769 3.01794 13.0769 3.25V12C13.0769 12.2321 12.9797 12.4546 12.8066 12.6187C12.6334 12.7828 12.3987 12.875 12.1538 12.875ZM2.92308 5C2.92308 4.76794 3.02033 4.54538 3.19344 4.38128C3.36655 4.21719 3.60134 4.125 3.84615 4.125H10.3077C10.5525 4.125 10.7873 4.21719 10.9604 4.38128C11.1335 4.54538 11.2308 4.76794 11.2308 5V13.75C11.2308 13.9821 11.1335 14.2046 10.9604 14.3687C10.7873 14.5328 10.5525 14.625 10.3077 14.625H3.84615C3.60134 14.625 3.36655 14.5328 3.19344 14.3687C3.02033 14.2046 2.92308 13.9821 2.92308 13.75V5Z"
|
||||
fill="var(--text-color)"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function TutorialsIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle
|
||||
cx="8.157"
|
||||
cy="8.35866"
|
||||
r="6.17928"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M7.31894 7.8336L7.30273 7.72125C10.0583 7.32407 11.5796 5.74901 12.1058 5.09033L12.1945 5.1612C11.6598 5.83032 10.1146 7.43067 7.31894 7.8336Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M7.3313 8.19434C7.56713 8.19434 7.7583 8.00316 7.7583 7.76734C7.7583 7.53151 7.56713 7.34033 7.3313 7.34033C7.09547 7.34033 6.9043 7.53151 6.9043 7.76734C6.9043 8.00316 7.09547 8.19434 7.3313 8.19434Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M12.134 5.56787C12.3699 5.56787 12.561 5.3767 12.561 5.14087C12.561 4.90504 12.3699 4.71387 12.134 4.71387C11.8982 4.71387 11.707 4.90504 11.707 5.14087C11.707 5.3767 11.8982 5.56787 12.134 5.56787Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M5.67763 13.0492C5.15009 12.385 4.31304 10.9992 4.63359 9.18018L4.74534 9.20001C4.43251 10.9751 5.25078 12.3292 5.76636 12.9785L5.67763 13.0492Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M4.68921 9.63867C4.92504 9.63867 5.11621 9.4475 5.11621 9.21167C5.11621 8.97584 4.92504 8.78467 4.68921 8.78467C4.45338 8.78467 4.26221 8.97584 4.26221 9.21167C4.26221 9.4475 4.45338 9.63867 4.68921 9.63867Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M5.70923 13.4238C5.94506 13.4238 6.13623 13.2327 6.13623 12.9968C6.13623 12.761 5.94506 12.5698 5.70923 12.5698C5.4734 12.5698 5.28223 12.761 5.28223 12.9968C5.28223 13.2327 5.4734 13.4238 5.70923 13.4238Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M12.4429 9.6101L12.3293 9.60692C12.369 8.18736 11.8263 6.82867 10.801 5.7813C9.73352 4.69047 8.2434 4.07147 6.70876 4.0804L6.70801 3.96684C8.27081 3.96078 9.79333 4.58917 10.8822 5.70181C11.9291 6.77143 12.4833 8.1595 12.4429 9.6101Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M12.3792 10.0142C12.615 10.0142 12.8062 9.82299 12.8062 9.58716C12.8062 9.35133 12.615 9.16016 12.3792 9.16016C12.1433 9.16016 11.9521 9.35133 11.9521 9.58716C11.9521 9.82299 12.1433 10.0142 12.3792 10.0142Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M6.72974 4.4585C6.96556 4.4585 7.15674 4.26732 7.15674 4.0315C7.15674 3.79567 6.96556 3.60449 6.72974 3.60449C6.49391 3.60449 6.30273 3.79567 6.30273 4.0315C6.30273 4.26732 6.49391 4.4585 6.72974 4.4585Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M8.93738 12.7561C5.51197 12.5871 3.18964 10.3443 2.15833 8.30167C1.40017 6.79989 1.28161 5.33657 1.84898 4.48256C2.21511 3.93139 2.7529 3.64179 3.57572 3.69903L3.45825 3.81649C2.67632 3.76183 2.28567 4.03042 1.94346 4.5454C1.39865 5.36549 1.51979 6.78505 2.25963 8.25049C3.27641 10.2647 5.56617 12.476 8.94298 12.6426L8.93738 12.7561Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M4.12372 13.5272C2.54078 13.2677 1.46328 11.9915 1.38697 10.4835C1.31368 9.03292 2.2066 7.3084 4.36675 6.72559L4.39628 6.83521C2.2973 7.40152 1.42936 9.07259 1.50053 10.4778C1.54767 11.4101 2.02721 12.4642 3.18398 12.9967C3.46147 13.1244 3.45807 13.0965 3.77132 13.2139L4.12372 13.5272Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M4.36157 7.21436C4.5974 7.21436 4.78858 7.02318 4.78858 6.78735C4.78858 6.55153 4.5974 6.36035 4.36157 6.36035C4.12575 6.36035 3.93457 6.55153 3.93457 6.78735C3.93457 7.02318 4.12575 7.21436 4.36157 7.21436Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M11.5155 15.1026C11.4663 15.1026 11.4165 15.1003 11.3659 15.0956C10.4065 15.0064 9.53752 14.1202 9.04102 12.7247L9.14807 12.6865C9.62928 14.0393 10.4622 14.8976 11.3764 14.9825C11.8685 15.0293 12.3041 14.8309 12.5152 14.4681C12.7337 14.0928 12.7265 13.7453 12.3977 13.2744L12.5152 13.1569C12.8703 13.6657 12.8548 14.1099 12.6133 14.5252C12.4016 14.8889 11.9895 15.1026 11.5155 15.1026Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M8.9187 13.1187C9.15453 13.1187 9.34571 12.9275 9.34571 12.6917C9.34571 12.4558 9.15453 12.2646 8.9187 12.2646C8.68287 12.2646 8.4917 12.4558 8.4917 12.6917C8.4917 12.9275 8.68287 13.1187 8.9187 13.1187Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M10.0987 3.65056L9.99072 3.61513C10.2487 2.83274 10.7045 2.32867 11.2414 2.23252C11.572 2.17286 11.8969 2.28566 12.0886 2.52597C12.2781 2.76339 12.4042 2.98817 12.2684 3.30782L12.1509 3.19035C12.2699 2.91023 12.1625 2.80064 12.0001 2.59683C11.8344 2.38923 11.5514 2.29248 11.2616 2.34441C10.7669 2.43284 10.3432 2.90906 10.0987 3.65056Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M10.0535 4.04004C10.2893 4.04004 10.4805 3.84887 10.4805 3.61304C10.4805 3.37721 10.2893 3.18604 10.0535 3.18604C9.81764 3.18604 9.62646 3.37721 9.62646 3.61304C9.62646 3.84887 9.81764 4.04004 10.0535 4.04004Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function DocumentationIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8 5.10589C7.2666 4.17245 6.13604 3.23901 3.33413 3.17051C3.15009 3.16602 3 3.3155 3 3.4996C3 4.86525 3 10.0354 3 11.5645C3 11.7486 3.1501 11.8932 3.33409 11.8992C6.13603 11.9908 7.2666 13.233 8 14.1665M8 5.10589C8.7334 4.17245 9.86393 3.23901 12.6659 3.17051C12.8499 3.16602 13 3.31214 13 3.49624C13 5.02281 13 10.0374 13 11.564C13 11.7481 12.8499 11.8932 12.6659 11.8992C9.864 11.9908 8.7334 13.233 8 14.1665M8 5.10589V14.1665"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M12.8232 4.5H14.333C14.5171 4.5 14.6663 4.64924 14.6663 4.83333V13.526C14.6663 13.7957 14.3485 13.9749 14.102 13.8654C13.5719 13.6299 12.6873 13.3421 11.5291 13.3421C9.56827 13.3421 7.99967 14.5 7.99967 14.5C7.99967 14.5 6.43105 13.3421 4.47026 13.3421C3.31197 13.3421 2.42738 13.6299 1.89732 13.8654C1.65079 13.9749 1.33301 13.7957 1.33301 13.526V4.83333C1.33301 4.64924 1.48225 4.5 1.66634 4.5H3.17615"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function HelpIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="12"
|
||||
height="13"
|
||||
viewBox="0 0 12 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clipPath="url(#clip0_764_1941)">
|
||||
<path
|
||||
d="M6 12.5C2.6862 12.5 0 9.8138 0 6.5C0 3.1862 2.6862 0.5 6 0.5C9.3138 0.5 12 3.1862 12 6.5C12 9.8138 9.3138 12.5 6 12.5ZM3.552 4.8404V4.9016C3.552 4.98117 3.58361 5.05747 3.63987 5.11373C3.69613 5.16999 3.77244 5.2016 3.852 5.2016H4.4502C4.48952 5.2016 4.52845 5.19386 4.56478 5.17881C4.6011 5.16376 4.63411 5.14171 4.66191 5.11391C4.68971 5.08611 4.71176 5.0531 4.72681 5.01678C4.74186 4.98045 4.7496 4.94152 4.7496 4.9022C4.7496 4.1282 5.3484 3.7148 6.1536 3.7148C6.9384 3.7148 7.4544 4.1282 7.4544 4.7168C7.4544 5.2736 7.1652 5.5322 6.4428 5.8628L6.2364 5.9552C5.6274 6.224 5.4 6.626 5.4 7.3286V7.4C5.4 7.47957 5.43161 7.55587 5.48787 7.61213C5.54413 7.66839 5.62044 7.7 5.7 7.7H6.2982C6.33752 7.7 6.37645 7.69226 6.41278 7.67721C6.4491 7.66216 6.48211 7.64011 6.50991 7.61231C6.53771 7.58451 6.55976 7.5515 6.57481 7.51518C6.58986 7.47885 6.5976 7.43992 6.5976 7.4006C6.5976 7.091 6.6804 6.9668 6.9276 6.8534L7.1346 6.7604C8.0016 6.368 8.652 5.852 8.652 4.7264V4.6646C8.652 3.4778 7.62 2.6 6.1536 2.6C4.6668 2.6 3.552 3.4568 3.552 4.8404ZM5.1 9.4946C5.1 10.0148 5.4954 10.4 5.9946 10.4C6.5046 10.4 6.9 10.0148 6.9 9.4946C6.9 8.9744 6.5046 8.6 5.9946 8.6C5.4954 8.6 5.1 8.9744 5.1 9.4946Z"
|
||||
fill="var(--text-color)"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_764_1941">
|
||||
<rect
|
||||
width="12"
|
||||
height="12"
|
||||
fill="white"
|
||||
transform="translate(0 0.5)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function LogoutIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M4 3.5C4.00605 2.41248 4.05428 1.82353 4.43847 1.43934C4.87781 1 5.58489 1 6.99914 1H7.49914C8.91334 1 9.62044 1 10.0598 1.43934C10.4991 1.87868 10.4991 2.58578 10.4991 4V8C10.4991 9.4142 10.4991 10.1213 10.0598 10.5606C9.62044 11 8.91334 11 7.49914 11H6.99914C5.58489 11 4.87781 11 4.43847 10.5606C4.05428 10.1764 4.00605 9.5875 4 8.5"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
<path
|
||||
opacity="0.5"
|
||||
d="M4 9.75C2.82149 9.75 2.23223 9.75 1.86611 9.3839C1.5 9.01775 1.5 8.4285 1.5 7.25V4.75C1.5 3.57149 1.5 2.98224 1.86611 2.61612C2.23223 2.25 2.82149 2.25 4 2.25"
|
||||
stroke="var(--text-color)"
|
||||
/>
|
||||
<path
|
||||
d="M7.5 6H3M3 6L4 7M3 6L4 5"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
export function NotificationIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M10 12.8335C10 13.3639 9.78927 13.8726 9.4142 14.2477C9.03913 14.6228 8.5304 14.8335 8 14.8335C7.4696 14.8335 6.96087 14.6228 6.58579 14.2477C6.21072 13.8726 6 13.3639 6 12.8335"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M3.72064 12.1667C3.39434 12.0974 3.10586 11.9084 2.91209 11.6369C2.71832 11.3653 2.63337 11.0311 2.67399 10.7L3.34066 5.29332C3.51087 4.18175 4.07672 3.16901 4.93414 2.44143C5.79156 1.71384 6.88287 1.32036 8.00734 1.33332C9.1318 1.32036 10.2231 1.71384 11.0805 2.44143C11.9379 3.16901 12.5038 4.18175 12.674 5.29332L13.3407 10.7C13.3815 11.0301 13.2975 11.3636 13.1051 11.635C12.9127 11.9063 12.6257 12.096 12.3007 12.1667C9.47907 12.8297 6.54222 12.8297 3.72064 12.1667Z"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function HomeIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M6.91304 13.5V12.8333C6.91304 12.281 7.36076 11.8333 7.91304 11.8333H8.95652C9.50881 11.8333 9.95652 12.281 9.95652 12.8333V13.5C9.95652 14.0523 10.4042 14.5 10.9565 14.5H12C12.5523 14.5 13 14.0523 13 13.5V7.38889L8.21739 2.5L3 7.38889V13.5C3 14.0523 3.44772 14.5 4 14.5H5.91304C6.46533 14.5 6.91304 14.0523 6.91304 13.5Z"
|
||||
stroke="var(--text-color)"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function ProjectsIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M12.1538 1.5H5.69231C5.20268 1.5 4.7331 1.68437 4.38688 2.01256C4.04066 2.34075 3.84615 2.78587 3.84615 3.25C3.35652 3.25 2.88695 3.43437 2.54073 3.76256C2.1945 4.09075 2 4.53587 2 5V13.75C2 14.2141 2.1945 14.6592 2.54073 14.9874C2.88695 15.3156 3.35652 15.5 3.84615 15.5H10.3077C10.7973 15.5 11.2669 15.3156 11.6131 14.9874C11.9593 14.6592 12.1538 14.2141 12.1538 13.75C12.6435 13.75 13.1131 13.5656 13.4593 13.2374C13.8055 12.9092 14 12.4641 14 12V3.25C14 2.78587 13.8055 2.34075 13.4593 2.01256C13.1131 1.68437 12.6435 1.5 12.1538 1.5ZM12.1538 12.875V5C12.1538 4.53587 11.9593 4.09075 11.6131 3.76256C11.2669 3.43437 10.7973 3.25 10.3077 3.25H4.76923C4.76923 3.01794 4.86648 2.79538 5.03959 2.63128C5.2127 2.46719 5.44749 2.375 5.69231 2.375H12.1538C12.3987 2.375 12.6334 2.46719 12.8066 2.63128C12.9797 2.79538 13.0769 3.01794 13.0769 3.25V12C13.0769 12.2321 12.9797 12.4546 12.8066 12.6187C12.6334 12.7828 12.3987 12.875 12.1538 12.875ZM2.92308 5C2.92308 4.76794 3.02033 4.54538 3.19344 4.38128C3.36655 4.21719 3.60134 4.125 3.84615 4.125H10.3077C10.5525 4.125 10.7873 4.21719 10.9604 4.38128C11.1335 4.54538 11.2308 4.76794 11.2308 5V13.75C11.2308 13.9821 11.1335 14.2046 10.9604 14.3687C10.7873 14.5328 10.5525 14.625 10.3077 14.625H3.84615C3.60134 14.625 3.36655 14.5328 3.19344 14.3687C3.02033 14.2046 2.92308 13.9821 2.92308 13.75V5Z"
|
||||
fill="var(--text-color)"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function TutorialsIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<circle
|
||||
cx="8.157"
|
||||
cy="8.35866"
|
||||
r="6.17928"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M7.31894 7.8336L7.30273 7.72125C10.0583 7.32407 11.5796 5.74901 12.1058 5.09033L12.1945 5.1612C11.6598 5.83032 10.1146 7.43067 7.31894 7.8336Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M7.3313 8.19434C7.56713 8.19434 7.7583 8.00316 7.7583 7.76734C7.7583 7.53151 7.56713 7.34033 7.3313 7.34033C7.09547 7.34033 6.9043 7.53151 6.9043 7.76734C6.9043 8.00316 7.09547 8.19434 7.3313 8.19434Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M12.134 5.56787C12.3699 5.56787 12.561 5.3767 12.561 5.14087C12.561 4.90504 12.3699 4.71387 12.134 4.71387C11.8982 4.71387 11.707 4.90504 11.707 5.14087C11.707 5.3767 11.8982 5.56787 12.134 5.56787Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M5.67763 13.0492C5.15009 12.385 4.31304 10.9992 4.63359 9.18018L4.74534 9.20001C4.43251 10.9751 5.25078 12.3292 5.76636 12.9785L5.67763 13.0492Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M4.68921 9.63867C4.92504 9.63867 5.11621 9.4475 5.11621 9.21167C5.11621 8.97584 4.92504 8.78467 4.68921 8.78467C4.45338 8.78467 4.26221 8.97584 4.26221 9.21167C4.26221 9.4475 4.45338 9.63867 4.68921 9.63867Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M5.70923 13.4238C5.94506 13.4238 6.13623 13.2327 6.13623 12.9968C6.13623 12.761 5.94506 12.5698 5.70923 12.5698C5.4734 12.5698 5.28223 12.761 5.28223 12.9968C5.28223 13.2327 5.4734 13.4238 5.70923 13.4238Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M12.4429 9.6101L12.3293 9.60692C12.369 8.18736 11.8263 6.82867 10.801 5.7813C9.73352 4.69047 8.2434 4.07147 6.70876 4.0804L6.70801 3.96684C8.27081 3.96078 9.79333 4.58917 10.8822 5.70181C11.9291 6.77143 12.4833 8.1595 12.4429 9.6101Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M12.3792 10.0142C12.615 10.0142 12.8062 9.82299 12.8062 9.58716C12.8062 9.35133 12.615 9.16016 12.3792 9.16016C12.1433 9.16016 11.9521 9.35133 11.9521 9.58716C11.9521 9.82299 12.1433 10.0142 12.3792 10.0142Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M6.72974 4.4585C6.96556 4.4585 7.15674 4.26732 7.15674 4.0315C7.15674 3.79567 6.96556 3.60449 6.72974 3.60449C6.49391 3.60449 6.30273 3.79567 6.30273 4.0315C6.30273 4.26732 6.49391 4.4585 6.72974 4.4585Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M8.93738 12.7561C5.51197 12.5871 3.18964 10.3443 2.15833 8.30167C1.40017 6.79989 1.28161 5.33657 1.84898 4.48256C2.21511 3.93139 2.7529 3.64179 3.57572 3.69903L3.45825 3.81649C2.67632 3.76183 2.28567 4.03042 1.94346 4.5454C1.39865 5.36549 1.51979 6.78505 2.25963 8.25049C3.27641 10.2647 5.56617 12.476 8.94298 12.6426L8.93738 12.7561Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M4.12372 13.5272C2.54078 13.2677 1.46328 11.9915 1.38697 10.4835C1.31368 9.03292 2.2066 7.3084 4.36675 6.72559L4.39628 6.83521C2.2973 7.40152 1.42936 9.07259 1.50053 10.4778C1.54767 11.4101 2.02721 12.4642 3.18398 12.9967C3.46147 13.1244 3.45807 13.0965 3.77132 13.2139L4.12372 13.5272Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M4.36157 7.21436C4.5974 7.21436 4.78858 7.02318 4.78858 6.78735C4.78858 6.55153 4.5974 6.36035 4.36157 6.36035C4.12575 6.36035 3.93457 6.55153 3.93457 6.78735C3.93457 7.02318 4.12575 7.21436 4.36157 7.21436Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M11.5155 15.1026C11.4663 15.1026 11.4165 15.1003 11.3659 15.0956C10.4065 15.0064 9.53752 14.1202 9.04102 12.7247L9.14807 12.6865C9.62928 14.0393 10.4622 14.8976 11.3764 14.9825C11.8685 15.0293 12.3041 14.8309 12.5152 14.4681C12.7337 14.0928 12.7265 13.7453 12.3977 13.2744L12.5152 13.1569C12.8703 13.6657 12.8548 14.1099 12.6133 14.5252C12.4016 14.8889 11.9895 15.1026 11.5155 15.1026Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M8.9187 13.1187C9.15453 13.1187 9.34571 12.9275 9.34571 12.6917C9.34571 12.4558 9.15453 12.2646 8.9187 12.2646C8.68287 12.2646 8.4917 12.4558 8.4917 12.6917C8.4917 12.9275 8.68287 13.1187 8.9187 13.1187Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M10.0987 3.65056L9.99072 3.61513C10.2487 2.83274 10.7045 2.32867 11.2414 2.23252C11.572 2.17286 11.8969 2.28566 12.0886 2.52597C12.2781 2.76339 12.4042 2.98817 12.2684 3.30782L12.1509 3.19035C12.2699 2.91023 12.1625 2.80064 12.0001 2.59683C11.8344 2.38923 11.5514 2.29248 11.2616 2.34441C10.7669 2.43284 10.3432 2.90906 10.0987 3.65056Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
<path
|
||||
d="M10.0535 4.04004C10.2893 4.04004 10.4805 3.84887 10.4805 3.61304C10.4805 3.37721 10.2893 3.18604 10.0535 3.18604C9.81764 3.18604 9.62646 3.37721 9.62646 3.61304C9.62646 3.84887 9.81764 4.04004 10.0535 4.04004Z"
|
||||
fill="var(--text-color)"
|
||||
stroke="var(--text-color)"
|
||||
strokeWidth="0.562865"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function DocumentationIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="16"
|
||||
height="17"
|
||||
viewBox="0 0 16 17"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M8 5.10589C7.2666 4.17245 6.13604 3.23901 3.33413 3.17051C3.15009 3.16602 3 3.3155 3 3.4996C3 4.86525 3 10.0354 3 11.5645C3 11.7486 3.1501 11.8932 3.33409 11.8992C6.13603 11.9908 7.2666 13.233 8 14.1665M8 5.10589C8.7334 4.17245 9.86393 3.23901 12.6659 3.17051C12.8499 3.16602 13 3.31214 13 3.49624C13 5.02281 13 10.0374 13 11.564C13 11.7481 12.8499 11.8932 12.6659 11.8992C9.864 11.9908 8.7334 13.233 8 14.1665M8 5.10589V14.1665"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M12.8232 4.5H14.333C14.5171 4.5 14.6663 4.64924 14.6663 4.83333V13.526C14.6663 13.7957 14.3485 13.9749 14.102 13.8654C13.5719 13.6299 12.6873 13.3421 11.5291 13.3421C9.56827 13.3421 7.99967 14.5 7.99967 14.5C7.99967 14.5 6.43105 13.3421 4.47026 13.3421C3.31197 13.3421 2.42738 13.6299 1.89732 13.8654C1.65079 13.9749 1.33301 13.7957 1.33301 13.526V4.83333C1.33301 4.64924 1.48225 4.5 1.66634 4.5H3.17615"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function HelpIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="12"
|
||||
height="13"
|
||||
viewBox="0 0 12 13"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clipPath="url(#clip0_764_1941)">
|
||||
<path
|
||||
d="M6 12.5C2.6862 12.5 0 9.8138 0 6.5C0 3.1862 2.6862 0.5 6 0.5C9.3138 0.5 12 3.1862 12 6.5C12 9.8138 9.3138 12.5 6 12.5ZM3.552 4.8404V4.9016C3.552 4.98117 3.58361 5.05747 3.63987 5.11373C3.69613 5.16999 3.77244 5.2016 3.852 5.2016H4.4502C4.48952 5.2016 4.52845 5.19386 4.56478 5.17881C4.6011 5.16376 4.63411 5.14171 4.66191 5.11391C4.68971 5.08611 4.71176 5.0531 4.72681 5.01678C4.74186 4.98045 4.7496 4.94152 4.7496 4.9022C4.7496 4.1282 5.3484 3.7148 6.1536 3.7148C6.9384 3.7148 7.4544 4.1282 7.4544 4.7168C7.4544 5.2736 7.1652 5.5322 6.4428 5.8628L6.2364 5.9552C5.6274 6.224 5.4 6.626 5.4 7.3286V7.4C5.4 7.47957 5.43161 7.55587 5.48787 7.61213C5.54413 7.66839 5.62044 7.7 5.7 7.7H6.2982C6.33752 7.7 6.37645 7.69226 6.41278 7.67721C6.4491 7.66216 6.48211 7.64011 6.50991 7.61231C6.53771 7.58451 6.55976 7.5515 6.57481 7.51518C6.58986 7.47885 6.5976 7.43992 6.5976 7.4006C6.5976 7.091 6.6804 6.9668 6.9276 6.8534L7.1346 6.7604C8.0016 6.368 8.652 5.852 8.652 4.7264V4.6646C8.652 3.4778 7.62 2.6 6.1536 2.6C4.6668 2.6 3.552 3.4568 3.552 4.8404ZM5.1 9.4946C5.1 10.0148 5.4954 10.4 5.9946 10.4C6.5046 10.4 6.9 10.0148 6.9 9.4946C6.9 8.9744 6.5046 8.6 5.9946 8.6C5.4954 8.6 5.1 8.9744 5.1 9.4946Z"
|
||||
fill="var(--text-color)"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_764_1941">
|
||||
<rect
|
||||
width="12"
|
||||
height="12"
|
||||
fill="white"
|
||||
transform="translate(0 0.5)"
|
||||
/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export function LogoutIcon() {
|
||||
return (
|
||||
<svg
|
||||
width="12"
|
||||
height="12"
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M4 3.5C4.00605 2.41248 4.05428 1.82353 4.43847 1.43934C4.87781 1 5.58489 1 6.99914 1H7.49914C8.91334 1 9.62044 1 10.0598 1.43934C10.4991 1.87868 10.4991 2.58578 10.4991 4V8C10.4991 9.4142 10.4991 10.1213 10.0598 10.5606C9.62044 11 8.91334 11 7.49914 11H6.99914C5.58489 11 4.87781 11 4.43847 10.5606C4.05428 10.1764 4.00605 9.5875 4 8.5"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
/>
|
||||
<path
|
||||
opacity="0.5"
|
||||
d="M4 9.75C2.82149 9.75 2.23223 9.75 1.86611 9.3839C1.5 9.01775 1.5 8.4285 1.5 7.25V4.75C1.5 3.57149 1.5 2.98224 1.86611 2.61612C2.23223 2.25 2.82149 2.25 4 2.25"
|
||||
stroke="var(--text-color)"
|
||||
/>
|
||||
<path
|
||||
d="M7.5 6H3M3 6L4 7M3 6L4 5"
|
||||
stroke="var(--text-color)"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
import React from "react";
|
||||
import { KebabIcon } from "../../icons/ExportCommonIcons";
|
||||
import img from "../../../assets/image/image.png"
|
||||
|
||||
const DashboardCard:React.FC = () => {
|
||||
return (
|
||||
<div className="dashboard-card-container">
|
||||
<div className="preview-container">
|
||||
<img src={img} alt="" />
|
||||
</div>
|
||||
<div className="project-details-container">
|
||||
<div className="project-details">
|
||||
<div className="project-name">Untitled</div>
|
||||
<div className="project-data">24-12-2025</div>
|
||||
</div>
|
||||
<div className="users-list-container">
|
||||
<div className="user-profile">V</div>
|
||||
<KebabIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardCard;
|
||||
import React from "react";
|
||||
import { KebabIcon } from "../../icons/ExportCommonIcons";
|
||||
import img from "../../../assets/image/image.png"
|
||||
|
||||
const DashboardCard:React.FC = () => {
|
||||
return (
|
||||
<div className="dashboard-card-container">
|
||||
<div className="preview-container">
|
||||
<img src={img} alt="" />
|
||||
</div>
|
||||
<div className="project-details-container">
|
||||
<div className="project-details">
|
||||
<div className="project-name">Untitled</div>
|
||||
<div className="project-data">24-12-2025</div>
|
||||
</div>
|
||||
<div className="users-list-container">
|
||||
<div className="user-profile">V</div>
|
||||
<KebabIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardCard;
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import React from "react";
|
||||
import DashboardCard from "./DashboardCard";
|
||||
import DashboardNavBar from "./DashboardNavBar";
|
||||
import MarketPlaceBanner from "./MarketPlaceBanner";
|
||||
|
||||
const DashboardHome: React.FC = () => {
|
||||
return (
|
||||
<div className="dashboard-home-container">
|
||||
<DashboardNavBar page={"home"} />
|
||||
<MarketPlaceBanner />
|
||||
<div className="container">
|
||||
<div className="header">Recents</div>
|
||||
<div className="cards-container">
|
||||
<DashboardCard />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardHome;
|
||||
import React from "react";
|
||||
import DashboardCard from "./DashboardCard";
|
||||
import DashboardNavBar from "./DashboardNavBar";
|
||||
import MarketPlaceBanner from "./MarketPlaceBanner";
|
||||
|
||||
const DashboardHome: React.FC = () => {
|
||||
return (
|
||||
<div className="dashboard-home-container">
|
||||
<DashboardNavBar page={"home"} />
|
||||
<MarketPlaceBanner />
|
||||
<div className="container">
|
||||
<div className="header">Recents</div>
|
||||
<div className="cards-container">
|
||||
<DashboardCard />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardHome;
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
import React from "react";
|
||||
import { CartIcon } from "../../icons/ExportModuleIcons";
|
||||
import Search from "../../ui/inputs/Search";
|
||||
|
||||
interface DashboardNavBarProps {
|
||||
page: React.ReactNode;
|
||||
}
|
||||
|
||||
const DashboardNavBar: React.FC<DashboardNavBarProps> = ({ page }) => {
|
||||
return (
|
||||
<div className="dashboard-navbar-container">
|
||||
<div className="title">{page}</div>
|
||||
<div className="market-place-button">
|
||||
<CartIcon isActive /> Market Place
|
||||
</div>
|
||||
<Search onChange={() => {}} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardNavBar;
|
||||
import React from "react";
|
||||
import { CartIcon } from "../../icons/ExportModuleIcons";
|
||||
import Search from "../../ui/inputs/Search";
|
||||
|
||||
interface DashboardNavBarProps {
|
||||
page: React.ReactNode;
|
||||
}
|
||||
|
||||
const DashboardNavBar: React.FC<DashboardNavBarProps> = ({ page }) => {
|
||||
return (
|
||||
<div className="dashboard-navbar-container">
|
||||
<div className="title">{page}</div>
|
||||
<div className="market-place-button">
|
||||
<CartIcon isActive /> Market Place
|
||||
</div>
|
||||
<Search onChange={() => {}} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default DashboardNavBar;
|
||||
|
|
|
@ -1,44 +1,44 @@
|
|||
import React from "react";
|
||||
import banner from "../../../assets/image/banner.png";
|
||||
|
||||
const MarketPlaceBanner = () => {
|
||||
return (
|
||||
<div className="market-place-banner-container">
|
||||
{/* market place banner */}
|
||||
<img src={banner} alt="" />
|
||||
<div className="hero-text">
|
||||
NEW
|
||||
<br /> FALL
|
||||
<br /> COLLECTION
|
||||
</div>
|
||||
<div className="context">Unlock Creativity with Premium 3D Assets!</div>
|
||||
<div className="arrow-context">
|
||||
<svg
|
||||
width="169"
|
||||
height="120"
|
||||
viewBox="0 0 169 120"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M167.189 2C154.638 36.335 104.466 106.204 4.18872 111"
|
||||
stroke="white"
|
||||
stroke-width="3"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M10.662 118.326L1.59439 111.524L9.47334 103.374"
|
||||
stroke="white"
|
||||
stroke-width="3"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="explore-button">Explore Now</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MarketPlaceBanner;
|
||||
import React from "react";
|
||||
import banner from "../../../assets/image/banner.png";
|
||||
|
||||
const MarketPlaceBanner = () => {
|
||||
return (
|
||||
<div className="market-place-banner-container">
|
||||
{/* market place banner */}
|
||||
<img src={banner} alt="" />
|
||||
<div className="hero-text">
|
||||
NEW
|
||||
<br /> FALL
|
||||
<br /> COLLECTION
|
||||
</div>
|
||||
<div className="context">Unlock Creativity with Premium 3D Assets!</div>
|
||||
<div className="arrow-context">
|
||||
<svg
|
||||
width="169"
|
||||
height="120"
|
||||
viewBox="0 0 169 120"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
d="M167.189 2C154.638 36.335 104.466 106.204 4.18872 111"
|
||||
stroke="white"
|
||||
stroke-width="3"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M10.662 118.326L1.59439 111.524L9.47334 103.374"
|
||||
stroke="white"
|
||||
stroke-width="3"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div className="explore-button">Explore Now</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default MarketPlaceBanner;
|
||||
|
|
|
@ -1,69 +1,69 @@
|
|||
import React from "react";
|
||||
import {
|
||||
DocumentationIcon,
|
||||
HelpIcon,
|
||||
HomeIcon,
|
||||
LogoutIcon,
|
||||
NotificationIcon,
|
||||
ProjectsIcon,
|
||||
TutorialsIcon,
|
||||
} from "../../icons/DashboardIcon";
|
||||
import { SettingsIcon, TrashIcon } from "../../icons/ExportCommonIcons";
|
||||
|
||||
const SidePannel: React.FC = () => {
|
||||
const userName = localStorage.getItem("userName") || "Anonymous";
|
||||
return (
|
||||
<div className="side-pannel-container">
|
||||
<div className="side-pannel-header">
|
||||
<div className="user-container">
|
||||
<div className="user-profile">{userName[0]}</div>
|
||||
<div className="user-name">{userName}</div>
|
||||
</div>
|
||||
<div className="notifications-container">
|
||||
<NotificationIcon />
|
||||
</div>
|
||||
</div>
|
||||
<div className="new-project-button">+ New project</div>
|
||||
<div className="side-bar-content-container">
|
||||
<div className="side-bar-options-container">
|
||||
<div className="option-list active">
|
||||
<HomeIcon />
|
||||
Home
|
||||
</div>
|
||||
<div className="option-list" title="coming soon">
|
||||
<ProjectsIcon />
|
||||
Projects
|
||||
</div>
|
||||
<div className="option-list" title="coming soon">
|
||||
<TrashIcon />
|
||||
Trash
|
||||
</div>
|
||||
<div className="option-list" title="coming soon">
|
||||
<TutorialsIcon />
|
||||
Tutorials
|
||||
</div>
|
||||
<div className="option-list" title="coming soon">
|
||||
<DocumentationIcon />
|
||||
Documentation
|
||||
</div>
|
||||
</div>
|
||||
<div className="side-bar-options-container" title="coming soon">
|
||||
<div className="option-list">
|
||||
<SettingsIcon />
|
||||
Settings
|
||||
</div>
|
||||
<div className="option-list" style={{cursor: "pointer"}}>
|
||||
<LogoutIcon />
|
||||
Log out
|
||||
</div>
|
||||
<div className="option-list">
|
||||
<HelpIcon />
|
||||
Help & Feedback
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SidePannel;
|
||||
import React from "react";
|
||||
import {
|
||||
DocumentationIcon,
|
||||
HelpIcon,
|
||||
HomeIcon,
|
||||
LogoutIcon,
|
||||
NotificationIcon,
|
||||
ProjectsIcon,
|
||||
TutorialsIcon,
|
||||
} from "../../icons/DashboardIcon";
|
||||
import { SettingsIcon, TrashIcon } from "../../icons/ExportCommonIcons";
|
||||
|
||||
const SidePannel: React.FC = () => {
|
||||
const userName = localStorage.getItem("userName") || "Anonymous";
|
||||
return (
|
||||
<div className="side-pannel-container">
|
||||
<div className="side-pannel-header">
|
||||
<div className="user-container">
|
||||
<div className="user-profile">{userName[0]}</div>
|
||||
<div className="user-name">{userName}</div>
|
||||
</div>
|
||||
<div className="notifications-container">
|
||||
<NotificationIcon />
|
||||
</div>
|
||||
</div>
|
||||
<div className="new-project-button">+ New project</div>
|
||||
<div className="side-bar-content-container">
|
||||
<div className="side-bar-options-container">
|
||||
<div className="option-list active">
|
||||
<HomeIcon />
|
||||
Home
|
||||
</div>
|
||||
<div className="option-list" title="coming soon">
|
||||
<ProjectsIcon />
|
||||
Projects
|
||||
</div>
|
||||
<div className="option-list" title="coming soon">
|
||||
<TrashIcon />
|
||||
Trash
|
||||
</div>
|
||||
<div className="option-list" title="coming soon">
|
||||
<TutorialsIcon />
|
||||
Tutorials
|
||||
</div>
|
||||
<div className="option-list" title="coming soon">
|
||||
<DocumentationIcon />
|
||||
Documentation
|
||||
</div>
|
||||
</div>
|
||||
<div className="side-bar-options-container" title="coming soon">
|
||||
<div className="option-list">
|
||||
<SettingsIcon />
|
||||
Settings
|
||||
</div>
|
||||
<div className="option-list" style={{cursor: "pointer"}}>
|
||||
<LogoutIcon />
|
||||
Log out
|
||||
</div>
|
||||
<div className="option-list">
|
||||
<HelpIcon />
|
||||
Help & Feedback
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SidePannel;
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import MultiLevelDropdown from "../../../../ui/inputs/MultiLevelDropDown";
|
||||
import { AddIcon } from "../../../../icons/ExportCommonIcons";
|
||||
import RegularDropDown from "../../../../ui/inputs/RegularDropDown";
|
||||
import useChartStore from "../../../../../store/useChartStore";
|
||||
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
|
||||
import { useWidgetStore } from "../../../../../store/useWidgetStore";
|
||||
import axios from "axios";
|
||||
import RenameInput from "../../../../ui/inputs/RenameInput";
|
||||
|
||||
type Props = {};
|
||||
|
||||
const FlotingWidgetInput = (props: Props) => {
|
||||
const [widgetName, setWidgetName] = useState('Widget');
|
||||
const { setMeasurements, updateDuration, updateName } = useChartStore();
|
||||
const [duration, setDuration] = useState('1h')
|
||||
const [dropDowndata, setDropDownData] = useState({});
|
||||
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
|
||||
const { selectedZone } = useSelectedZoneStore();
|
||||
const { selectedChartId } = useWidgetStore();
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
const response = await axios.get(`http://${iotApiUrl}/getinput`);
|
||||
if (response.status === 200) {
|
||||
// console.log("dropdown data:", response.data);
|
||||
setDropDownData(response.data);
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("There was an error!", error);
|
||||
}
|
||||
};
|
||||
fetchZoneData();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchSavedInputes = async () => {
|
||||
if (selectedChartId.id !== "") {
|
||||
try {
|
||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${selectedChartId.id}/${organization}`);
|
||||
if (response.status === 200) {
|
||||
setSelections(response.data.Data.measurements)
|
||||
setDuration(response.data.Data.duration)
|
||||
setWidgetName(response.data.widgetName)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("There was an error!", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fetchSavedInputes();
|
||||
|
||||
}, [selectedChartId.id]);
|
||||
|
||||
// Sync Zustand state when component mounts
|
||||
useEffect(() => {
|
||||
setMeasurements(selections);
|
||||
updateDuration(duration);
|
||||
updateName(widgetName);
|
||||
}, [selections, duration, widgetName]);
|
||||
|
||||
|
||||
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
|
||||
try {
|
||||
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/floatwidget/save`, {
|
||||
organization: organization,
|
||||
zoneId: selectedZone.zoneId,
|
||||
widget: {
|
||||
id: selectedChartId.id,
|
||||
panel: selectedChartId.panel,
|
||||
widgetName: inputName,
|
||||
Data: {
|
||||
measurements: inputMeasurement,
|
||||
duration: inputDuration
|
||||
}
|
||||
}
|
||||
} as any);
|
||||
if (response.status === 200) {
|
||||
return true
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
return false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("There was an error!", error);
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
|
||||
|
||||
// async() => {
|
||||
const newSelections = { ...selections };
|
||||
if (selectedData === null) {
|
||||
delete newSelections[inputKey];
|
||||
} else {
|
||||
newSelections[inputKey] = selectedData;
|
||||
}
|
||||
// setMeasurements(newSelections); // Update Zustand store
|
||||
console.log(newSelections);
|
||||
if (await sendInputes(newSelections, duration, widgetName)) {
|
||||
setSelections(newSelections);
|
||||
}
|
||||
// sendInputes(newSelections, duration); // Send data to server
|
||||
// return newSelections;
|
||||
// };
|
||||
};
|
||||
|
||||
const handleSelectDuration = async (option: string) => {
|
||||
if (await sendInputes(selections, option, widgetName)) {
|
||||
setDuration(option);
|
||||
}
|
||||
// setDuration(option);
|
||||
};
|
||||
|
||||
const handleNameChange = async (name:any) => {
|
||||
console.log('name change requested',name);
|
||||
|
||||
if (await sendInputes(selections, duration, name)) {
|
||||
setWidgetName(name);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(6)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
return (
|
||||
<div key={index} className="datas">
|
||||
<div className="datas__label">Input {index + 1}</div>
|
||||
<div className="datas__class">
|
||||
<MultiLevelDropdown
|
||||
data={dropDowndata}
|
||||
onSelect={(selectedData) => handleSelect(inputKey, selectedData)}
|
||||
onUnselect={() => handleSelect(inputKey, null)}
|
||||
selectedValue={selections[inputKey]} // Load from Zustand
|
||||
/>
|
||||
<div className="icon">
|
||||
<AddIcon />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
<div>
|
||||
<div className="datas">
|
||||
<div className="datas__label">Duration</div>
|
||||
<div className="datas__class">
|
||||
<RegularDropDown
|
||||
header={duration}
|
||||
options={["1h", "2h", "12h"]}
|
||||
onSelect={handleSelectDuration}
|
||||
search={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default FlotingWidgetInput;
|
|
@ -58,11 +58,11 @@
|
|||
// name: string;
|
||||
// fields: string;
|
||||
// }
|
||||
|
||||
|
||||
// interface InputData {
|
||||
// [key: string]: Measurement;
|
||||
// }
|
||||
|
||||
|
||||
// const extractMeasurements = (input: InputData): Measurement[] => {
|
||||
// return Object.values(input);
|
||||
// };
|
||||
|
@ -71,7 +71,7 @@
|
|||
// const measurementsData = extractMeasurements(selections);
|
||||
// setMeasurements(measurementsData);
|
||||
// }, [selections]);
|
||||
|
||||
|
||||
|
||||
// return (
|
||||
// <>
|
||||
|
@ -125,20 +125,22 @@ import useChartStore from "../../../../../store/useChartStore";
|
|||
import { useSelectedZoneStore } from "../../../../../store/useZoneStore";
|
||||
import { useWidgetStore } from "../../../../../store/useWidgetStore";
|
||||
import axios from "axios";
|
||||
import RenameInput from "../../../../ui/inputs/RenameInput";
|
||||
|
||||
type Props = {};
|
||||
|
||||
const LineGrapInput = (props: Props) => {
|
||||
const { setMeasurements, updateDuration } = useChartStore();
|
||||
const [widgetName, setWidgetName] = useState('Widget');
|
||||
const { setMeasurements, updateDuration, updateName } = useChartStore();
|
||||
const [duration, setDuration] = useState('1h')
|
||||
const [dropDowndata, setDropDownData] = useState({});
|
||||
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
|
||||
const [selections, setSelections] = useState<Record<string, { name: string; fields: string }>>({});
|
||||
const { selectedZone } = useSelectedZoneStore();
|
||||
const { selectedChartId } = useWidgetStore();
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const fetchZoneData = async () => {
|
||||
try {
|
||||
|
@ -157,13 +159,14 @@ const LineGrapInput = (props: Props) => {
|
|||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchSavedInputes = async() => {
|
||||
const fetchSavedInputes = async () => {
|
||||
if (selectedChartId.id !== "") {
|
||||
try {
|
||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${selectedChartId.id}/${organization}`);
|
||||
if (response.status === 200) {
|
||||
setSelections(response.data.Data.measurements)
|
||||
setDuration(response.data.Data.duration)
|
||||
setWidgetName(response.data.widgetName)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
|
@ -181,17 +184,19 @@ const LineGrapInput = (props: Props) => {
|
|||
useEffect(() => {
|
||||
setMeasurements(selections);
|
||||
updateDuration(duration);
|
||||
}, [selections, duration]);
|
||||
updateName(widgetName);
|
||||
}, [selections, duration, widgetName]);
|
||||
|
||||
|
||||
const sendInputes = async(inputMeasurement: any, inputDuration: any) => {
|
||||
const sendInputes = async (inputMeasurement: any, inputDuration: any, inputName: any) => {
|
||||
try {
|
||||
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget/save`,{
|
||||
const response = await axios.post(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/widget/save`, {
|
||||
organization: organization,
|
||||
zoneId: selectedZone.zoneId,
|
||||
widget:{
|
||||
widget: {
|
||||
id: selectedChartId.id,
|
||||
panel: selectedChartId.panel,
|
||||
widgetName: inputName,
|
||||
Data: {
|
||||
measurements: inputMeasurement,
|
||||
duration: inputDuration
|
||||
|
@ -210,35 +215,47 @@ const LineGrapInput = (props: Props) => {
|
|||
}
|
||||
}
|
||||
|
||||
const handleSelect = async(inputKey: string, selectedData: { name: string; fields: string } | null) => {
|
||||
|
||||
// async() => {
|
||||
const newSelections = { ...selections };
|
||||
if (selectedData === null) {
|
||||
delete newSelections[inputKey];
|
||||
} else {
|
||||
newSelections[inputKey] = selectedData;
|
||||
}
|
||||
// setMeasurements(newSelections); // Update Zustand store
|
||||
console.log(newSelections);
|
||||
if ( await sendInputes(newSelections, duration)) {
|
||||
setSelections(newSelections);
|
||||
}
|
||||
// sendInputes(newSelections, duration); // Send data to server
|
||||
// return newSelections;
|
||||
const handleSelect = async (inputKey: string, selectedData: { name: string; fields: string } | null) => {
|
||||
|
||||
// async() => {
|
||||
const newSelections = { ...selections };
|
||||
if (selectedData === null) {
|
||||
delete newSelections[inputKey];
|
||||
} else {
|
||||
newSelections[inputKey] = selectedData;
|
||||
}
|
||||
// setMeasurements(newSelections); // Update Zustand store
|
||||
console.log(newSelections);
|
||||
if (await sendInputes(newSelections, duration, widgetName)) {
|
||||
setSelections(newSelections);
|
||||
}
|
||||
// sendInputes(newSelections, duration); // Send data to server
|
||||
// return newSelections;
|
||||
// };
|
||||
};
|
||||
|
||||
const handleSelectDuration = async(option: string) => {
|
||||
if ( await sendInputes(selections, option)) {
|
||||
const handleSelectDuration = async (option: string) => {
|
||||
if (await sendInputes(selections, option, widgetName)) {
|
||||
setDuration(option);
|
||||
}
|
||||
// setDuration(option);
|
||||
};
|
||||
|
||||
const handleNameChange = async (name:any) => {
|
||||
console.log('name change requested',name);
|
||||
|
||||
if (await sendInputes(selections, duration, name)) {
|
||||
setWidgetName(name);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="inputs-wrapper">
|
||||
<div className="datas">
|
||||
<div className="datas__label">Title</div>
|
||||
<RenameInput value={selectedChartId?.title || "untited"} onRename={handleNameChange}/>
|
||||
</div>
|
||||
{[...Array(6)].map((_, index) => {
|
||||
const inputKey = `input${index + 1}`;
|
||||
return (
|
||||
|
|
|
@ -3,6 +3,7 @@ import { useWidgetStore } from "../../../../../store/useWidgetStore";
|
|||
import { AddIcon, RemoveIcon } from "../../../../icons/ExportCommonIcons";
|
||||
import MultiLevelDropDown from "../../../../ui/inputs/MultiLevelDropDown";
|
||||
import LineGrapInput from "../IotInputCards/LineGrapInput";
|
||||
import RenameInput from "../../../../ui/inputs/RenameInput";
|
||||
|
||||
// Define the data structure for demonstration purposes
|
||||
const DATA_STRUCTURE = {
|
||||
|
@ -107,27 +108,36 @@ const Data = () => {
|
|||
[selectedChartId.id]: currentChartData.map((group) =>
|
||||
group.id === groupId
|
||||
? {
|
||||
...group,
|
||||
children: group.children.filter(
|
||||
(child) => child.id !== childId
|
||||
),
|
||||
}
|
||||
...group,
|
||||
children: group.children.filter(
|
||||
(child) => child.id !== childId
|
||||
),
|
||||
}
|
||||
: group
|
||||
),
|
||||
};
|
||||
});
|
||||
};
|
||||
console.log("selectedChartId", selectedChartId);
|
||||
|
||||
return (
|
||||
<div className="dataSideBar">
|
||||
{selectedChartId?.title && (
|
||||
{/* {selectedChartId?.title && (
|
||||
<div className="sideBarHeader">{selectedChartId?.title}</div>
|
||||
)}
|
||||
)} */}
|
||||
|
||||
|
||||
{/* <RenameInput value={selectedChartId?.title || "untited"} /> */}
|
||||
|
||||
{/* Render groups dynamically */}
|
||||
{
|
||||
chartDataGroups[selectedChartId?.id] && <LineGrapInput />
|
||||
chartDataGroups[selectedChartId?.id] &&
|
||||
<>
|
||||
<div className="sideBarHeader">2D Widget Input</div>
|
||||
<LineGrapInput />
|
||||
</>
|
||||
}
|
||||
|
||||
|
||||
{/* Info Box */}
|
||||
<div className="infoBox">
|
||||
<span className="infoIcon">i</span>
|
||||
|
|
|
@ -306,34 +306,20 @@ export const DraggableWidget = ({
|
|||
)}
|
||||
{widget.type === "doughnut" && (
|
||||
<DoughnutGraphComponent
|
||||
id={widget.id}
|
||||
type={widget.type}
|
||||
title={widget.title}
|
||||
fontSize={widget.fontSize}
|
||||
fontWeight={widget.fontWeight}
|
||||
data={{
|
||||
measurements: [
|
||||
{ name: "testDevice", fields: "powerConsumption" },
|
||||
{ name: "furnace", fields: "powerConsumption" },
|
||||
],
|
||||
interval: 1000,
|
||||
duration: "1h",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{widget.type === "polarArea" && (
|
||||
<PolarAreaGraphComponent
|
||||
id={widget.id}
|
||||
type={widget.type}
|
||||
title={widget.title}
|
||||
fontSize={widget.fontSize}
|
||||
fontWeight={widget.fontWeight}
|
||||
data={{
|
||||
measurements: [
|
||||
{ name: "testDevice", fields: "powerConsumption" },
|
||||
{ name: "furnace", fields: "powerConsumption" },
|
||||
],
|
||||
interval: 1000,
|
||||
duration: "1h",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -10,6 +10,10 @@ import { determinePosition } from "./functions/determinePosition";
|
|||
import { getActiveProperties } from "./functions/getActiveProperties";
|
||||
import { addingFloatingWidgets } from "../../../services/realTimeVisulization/zoneData/addFloatingWidgets";
|
||||
|
||||
import TotalCardComponent from "../realTimeVis/floating/TotalCardComponent";
|
||||
import WarehouseThroughputComponent from "../realTimeVis/floating/WarehouseThroughputComponent";
|
||||
import FleetEfficiencyComponent from "../realTimeVis/floating/FleetEfficiencyComponent";
|
||||
import { useWidgetStore } from "../../../store/useWidgetStore";
|
||||
const DroppedObjects: React.FC = () => {
|
||||
const zones = useDroppedObjectsStore((state) => state.zones);
|
||||
|
||||
|
@ -21,6 +25,7 @@ const DroppedObjects: React.FC = () => {
|
|||
index: number;
|
||||
} | null>(null);
|
||||
const [offset, setOffset] = useState<[number, number] | null>(null);
|
||||
const { setSelectedChartId } = useWidgetStore();
|
||||
const positionRef = useRef<[number, number] | null>(null);
|
||||
const animationRef = useRef<number | null>(null);
|
||||
const { activeModule } = useModuleStore();
|
||||
|
@ -29,9 +34,13 @@ const DroppedObjects: React.FC = () => {
|
|||
const zoneEntries = Object.entries(zones);
|
||||
if (zoneEntries.length === 0) return null; // No zone, nothing to render
|
||||
const [zoneName, zone] = zoneEntries[0]; // Only render the first zone
|
||||
console.log("zone", zone);
|
||||
|
||||
|
||||
|
||||
// Handle pointer down event
|
||||
function handlePointerDown(event: React.PointerEvent, index: number) {
|
||||
|
||||
const obj = zone.objects[index];
|
||||
const container = document.getElementById("real-time-vis-canvas");
|
||||
if (!container) return;
|
||||
|
@ -194,53 +203,21 @@ const DroppedObjects: React.FC = () => {
|
|||
// transition: draggingIndex?.index === index ? "none" : "transform 0.1s ease-out",
|
||||
}}
|
||||
onPointerDown={(event) => handlePointerDown(event, index)}
|
||||
onClick={() => {
|
||||
setSelectedChartId(obj)
|
||||
}}
|
||||
>
|
||||
{obj.className === "floating total-card" ? (
|
||||
<>
|
||||
<div className="header-wrapper">
|
||||
<div className="header">{obj.header}</div>
|
||||
<div className="data-values">
|
||||
<div className="value">{obj.value}</div>
|
||||
<div className="per">{obj.per}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="icon">
|
||||
<WalletIcon />
|
||||
</div>
|
||||
<TotalCardComponent object={obj} />
|
||||
</>
|
||||
) : obj.className === "warehouseThroughput floating" ? (
|
||||
<>
|
||||
<div className="header">
|
||||
<h2>Warehouse Throughput</h2>
|
||||
<p>
|
||||
<span>(+5) more</span> in 2025
|
||||
</p>
|
||||
</div>
|
||||
<div className="lineGraph" style={{ height: "100%" }}>
|
||||
{/* <Line data={lineGraphData} options={lineGraphOptions} /> */}
|
||||
</div>
|
||||
<WarehouseThroughputComponent />
|
||||
</>
|
||||
) : obj.className === "fleetEfficiency floating" ? (
|
||||
<>
|
||||
<h2 className="header">Fleet Efficiency</h2>
|
||||
<div className="progressContainer">
|
||||
<div className="progress">
|
||||
<div className="barOverflow">
|
||||
<div
|
||||
className="bar"
|
||||
style={{ transform: `rotate(${obj.value}deg)` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="scaleLabels">
|
||||
<span>0%</span>
|
||||
<div className="centerText">
|
||||
<div className="percentage">{obj.per}%</div>
|
||||
<div className="status">Optimal</div>
|
||||
</div>
|
||||
<span>100%</span>
|
||||
</div>
|
||||
<FleetEfficiencyComponent object={obj} />
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
|
|
|
@ -211,9 +211,10 @@ const BarGraphComponent = ({
|
|||
fontWeight = "Regular",
|
||||
}: ChartComponentProps) => {
|
||||
const { themeColor } = useThemeStore();
|
||||
const { measurements: chartMeasurements, duration: chartDuration } = useChartStore();
|
||||
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
|
||||
const [measurements, setmeasurements] = useState<any>({});
|
||||
const [duration, setDuration] = useState("1h")
|
||||
const [name, setName] = useState("Widget")
|
||||
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
|
||||
labels: [],
|
||||
datasets: [],
|
||||
|
@ -236,6 +237,10 @@ const BarGraphComponent = ({
|
|||
],
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("titleeeeeeeeeeeeeeeeeee",title);
|
||||
},[])
|
||||
|
||||
// Memoize Theme Colors
|
||||
const buttonActionColor = useMemo(() => themeColor[0] || "#5c87df", [themeColor]);
|
||||
const buttonAbortColor = useMemo(() => themeColor[1] || "#ffffff", [themeColor]);
|
||||
|
@ -270,7 +275,7 @@ const BarGraphComponent = ({
|
|||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: title,
|
||||
text: name,
|
||||
font: chartFontStyle,
|
||||
},
|
||||
legend: {
|
||||
|
@ -285,7 +290,7 @@ const BarGraphComponent = ({
|
|||
},
|
||||
},
|
||||
}),
|
||||
[title, chartFontStyle]
|
||||
[title, chartFontStyle, name]
|
||||
);
|
||||
|
||||
// useEffect(() => {console.log(measurements);
|
||||
|
@ -304,15 +309,12 @@ const BarGraphComponent = ({
|
|||
|
||||
|
||||
const startStream = () => {
|
||||
console.log("inputtttttttttt",inputData);
|
||||
socket.emit("lineInput", inputData);
|
||||
};
|
||||
|
||||
socket.on("connect", startStream);
|
||||
|
||||
socket.on("lineOutput", (response) => {
|
||||
console.log("responce dataaaaaaaaa",response.data);
|
||||
|
||||
const responseData = response.data;
|
||||
|
||||
// Extract timestamps and values
|
||||
|
@ -347,6 +349,7 @@ const BarGraphComponent = ({
|
|||
if (response.status === 200) {
|
||||
setmeasurements(response.data.Data.measurements)
|
||||
setDuration(response.data.Data.duration)
|
||||
setName(response.data.widgetName)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
|
@ -365,7 +368,7 @@ const BarGraphComponent = ({
|
|||
fetchSavedInputes();
|
||||
}
|
||||
}
|
||||
,[chartMeasurements, chartDuration])
|
||||
,[chartMeasurements, chartDuration, widgetName])
|
||||
|
||||
return <Bar data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
|
||||
};
|
||||
|
|
|
@ -1,22 +1,64 @@
|
|||
import { useMemo } from "react";
|
||||
import { Doughnut, Line } from "react-chartjs-2";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { Doughnut } from "react-chartjs-2";
|
||||
import io from "socket.io-client";
|
||||
import { useThemeStore } from "../../../../store/useThemeStore";
|
||||
import useChartStore from "../../../../store/useChartStore";
|
||||
import { useWidgetStore } from "../../../../store/useWidgetStore";
|
||||
import axios from "axios";
|
||||
|
||||
interface ChartComponentProps {
|
||||
id: string;
|
||||
type: any;
|
||||
title: string;
|
||||
fontFamily?: string;
|
||||
fontSize?: string;
|
||||
fontWeight?: "Light" | "Regular" | "Bold";
|
||||
data: any;
|
||||
}
|
||||
|
||||
const DoughnutGraphComponent = ({
|
||||
id,
|
||||
type,
|
||||
title,
|
||||
fontFamily,
|
||||
fontSize,
|
||||
fontWeight = "Regular",
|
||||
}: ChartComponentProps) => {
|
||||
// Memoize Font Weight Mapping
|
||||
const { themeColor } = useThemeStore();
|
||||
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
|
||||
const [measurements, setmeasurements] = useState<any>({});
|
||||
const [duration, setDuration] = useState("1h")
|
||||
const [name, setName] = useState("Widget")
|
||||
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
|
||||
labels: [],
|
||||
datasets: [],
|
||||
});
|
||||
const { selectedChartId } = useWidgetStore();
|
||||
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const defaultData = {
|
||||
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
|
||||
datasets: [
|
||||
{
|
||||
label: "Dataset",
|
||||
data: [12, 19, 3, 5, 2, 3],
|
||||
backgroundColor: ["#6f42c1"],
|
||||
borderColor: "#b392f0",
|
||||
borderWidth: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("titleeeeeeeeeeeeeeeeeee",title);
|
||||
},[])
|
||||
|
||||
// Memoize Theme Colors
|
||||
const buttonActionColor = useMemo(() => themeColor[0] || "#5c87df", [themeColor]);
|
||||
const buttonAbortColor = useMemo(() => themeColor[1] || "#ffffff", [themeColor]);
|
||||
|
||||
// Memoize Font Styling
|
||||
const chartFontWeightMap = useMemo(
|
||||
() => ({
|
||||
Light: "lighter" as const,
|
||||
|
@ -26,19 +68,9 @@ const DoughnutGraphComponent = ({
|
|||
[]
|
||||
);
|
||||
|
||||
// Parse and Memoize Font Size
|
||||
const fontSizeValue = useMemo(
|
||||
() => (fontSize ? parseInt(fontSize) : 12),
|
||||
[fontSize]
|
||||
);
|
||||
const fontSizeValue = useMemo(() => (fontSize ? parseInt(fontSize) : 12), [fontSize]);
|
||||
const fontWeightValue = useMemo(() => chartFontWeightMap[fontWeight], [fontWeight, chartFontWeightMap]);
|
||||
|
||||
// Determine and Memoize Font Weight
|
||||
const fontWeightValue = useMemo(
|
||||
() => chartFontWeightMap[fontWeight],
|
||||
[fontWeight, chartFontWeightMap]
|
||||
);
|
||||
|
||||
// Memoize Chart Font Style
|
||||
const chartFontStyle = useMemo(
|
||||
() => ({
|
||||
family: fontFamily || "Arial",
|
||||
|
@ -48,46 +80,110 @@ const DoughnutGraphComponent = ({
|
|||
[fontFamily, fontSizeValue, fontWeightValue]
|
||||
);
|
||||
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: title,
|
||||
font: chartFontStyle,
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
ticks: {
|
||||
display: false, // This hides the x-axis labels
|
||||
// Memoize Chart Options
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: name,
|
||||
font: chartFontStyle,
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
[title, chartFontStyle]
|
||||
);
|
||||
scales: {
|
||||
// x: {
|
||||
// ticks: {
|
||||
// display: true, // This hides the x-axis labels
|
||||
// },
|
||||
// },
|
||||
},
|
||||
}),
|
||||
[title, chartFontStyle, name]
|
||||
);
|
||||
|
||||
const chartData = {
|
||||
labels: ["January", "February", "March", "April", "May", "June", "July"],
|
||||
datasets: [
|
||||
{
|
||||
label: "My First Dataset",
|
||||
data: [65, 59, 80, 81, 56, 55, 40],
|
||||
backgroundColor: "#6f42c1", // Updated to #6f42c1 (Purple)
|
||||
borderColor: "#ffffff", // Keeping border color white
|
||||
borderWidth: 2,
|
||||
fill: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
// useEffect(() => {console.log(measurements);
|
||||
// },[measurements])
|
||||
|
||||
return <Doughnut data={chartData} options={options} />;
|
||||
useEffect(() => {
|
||||
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
|
||||
|
||||
const socket = io(`http://${iotApiUrl}`);
|
||||
|
||||
const inputData = {
|
||||
measurements,
|
||||
duration,
|
||||
interval: 1000,
|
||||
};
|
||||
|
||||
|
||||
const startStream = () => {
|
||||
socket.emit("lineInput", inputData);
|
||||
};
|
||||
|
||||
socket.on("connect", startStream);
|
||||
|
||||
socket.on("lineOutput", (response) => {
|
||||
const responseData = response.data;
|
||||
|
||||
// Extract timestamps and values
|
||||
const labels = responseData.time;
|
||||
const datasets = Object.keys(measurements).map((key) => {
|
||||
const measurement = measurements[key];
|
||||
const datasetKey = `${measurement.name}.${measurement.fields}`;
|
||||
return {
|
||||
label: datasetKey,
|
||||
data: responseData[datasetKey]?.values ?? [],
|
||||
backgroundColor: "#6f42c1",
|
||||
borderColor: "#b392f0",
|
||||
borderWidth: 1,
|
||||
};
|
||||
});
|
||||
|
||||
setChartData({ labels, datasets });
|
||||
});
|
||||
|
||||
return () => {
|
||||
socket.off("lineOutput");
|
||||
socket.emit("stop_stream"); // Stop streaming when component unmounts
|
||||
socket.disconnect();
|
||||
};
|
||||
}, [measurements, duration, iotApiUrl]);
|
||||
|
||||
const fetchSavedInputes = async() => {
|
||||
|
||||
if (id !== "") {
|
||||
try {
|
||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${id}/${organization}`);
|
||||
if (response.status === 200) {
|
||||
setmeasurements(response.data.Data.measurements)
|
||||
setDuration(response.data.Data.duration)
|
||||
setName(response.data.widgetName)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("There was an error!", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchSavedInputes();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedChartId?.id === id) {
|
||||
fetchSavedInputes();
|
||||
}
|
||||
}
|
||||
,[chartMeasurements, chartDuration, widgetName])
|
||||
|
||||
return <Doughnut data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
|
||||
};
|
||||
|
||||
export default DoughnutGraphComponent;
|
||||
export default DoughnutGraphComponent;
|
|
@ -24,9 +24,10 @@ const LineGraphComponent = ({
|
|||
fontWeight = "Regular",
|
||||
}: ChartComponentProps) => {
|
||||
const { themeColor } = useThemeStore();
|
||||
const { measurements: chartMeasurements, duration: chartDuration } = useChartStore();
|
||||
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
|
||||
const [measurements, setmeasurements] = useState<any>({});
|
||||
const [duration, setDuration] = useState("1h")
|
||||
const [name, setName] = useState("Widget")
|
||||
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
|
||||
labels: [],
|
||||
datasets: [],
|
||||
|
@ -49,6 +50,10 @@ const LineGraphComponent = ({
|
|||
],
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("titleeeeeeeeeeeeeeeeeee",title);
|
||||
},[])
|
||||
|
||||
// Memoize Theme Colors
|
||||
const buttonActionColor = useMemo(() => themeColor[0] || "#5c87df", [themeColor]);
|
||||
const buttonAbortColor = useMemo(() => themeColor[1] || "#ffffff", [themeColor]);
|
||||
|
@ -83,7 +88,7 @@ const LineGraphComponent = ({
|
|||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: title,
|
||||
text: name,
|
||||
font: chartFontStyle,
|
||||
},
|
||||
legend: {
|
||||
|
@ -98,7 +103,7 @@ const LineGraphComponent = ({
|
|||
},
|
||||
},
|
||||
}),
|
||||
[title, chartFontStyle]
|
||||
[title, chartFontStyle, name]
|
||||
);
|
||||
|
||||
// useEffect(() => {console.log(measurements);
|
||||
|
@ -157,6 +162,7 @@ const LineGraphComponent = ({
|
|||
if (response.status === 200) {
|
||||
setmeasurements(response.data.Data.measurements)
|
||||
setDuration(response.data.Data.duration)
|
||||
setName(response.data.widgetName)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
|
@ -175,7 +181,7 @@ const LineGraphComponent = ({
|
|||
fetchSavedInputes();
|
||||
}
|
||||
}
|
||||
,[chartMeasurements, chartDuration])
|
||||
,[chartMeasurements, chartDuration, widgetName])
|
||||
|
||||
return <Line data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
|
||||
};
|
||||
|
|
|
@ -210,9 +210,10 @@ const PieChartComponent = ({
|
|||
fontWeight = "Regular",
|
||||
}: ChartComponentProps) => {
|
||||
const { themeColor } = useThemeStore();
|
||||
const { measurements: chartMeasurements, duration: chartDuration } = useChartStore();
|
||||
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
|
||||
const [measurements, setmeasurements] = useState<any>({});
|
||||
const [duration, setDuration] = useState("1h")
|
||||
const [name, setName] = useState("Widget")
|
||||
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
|
||||
labels: [],
|
||||
datasets: [],
|
||||
|
@ -235,6 +236,10 @@ const PieChartComponent = ({
|
|||
],
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("titleeeeeeeeeeeeeeeeeee",title);
|
||||
},[])
|
||||
|
||||
// Memoize Theme Colors
|
||||
const buttonActionColor = useMemo(() => themeColor[0] || "#5c87df", [themeColor]);
|
||||
const buttonAbortColor = useMemo(() => themeColor[1] || "#ffffff", [themeColor]);
|
||||
|
@ -269,7 +274,7 @@ const PieChartComponent = ({
|
|||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: title,
|
||||
text: name,
|
||||
font: chartFontStyle,
|
||||
},
|
||||
legend: {
|
||||
|
@ -284,7 +289,7 @@ const PieChartComponent = ({
|
|||
// },
|
||||
},
|
||||
}),
|
||||
[title, chartFontStyle]
|
||||
[title, chartFontStyle, name]
|
||||
);
|
||||
|
||||
// useEffect(() => {console.log(measurements);
|
||||
|
@ -343,6 +348,7 @@ const PieChartComponent = ({
|
|||
if (response.status === 200) {
|
||||
setmeasurements(response.data.Data.measurements)
|
||||
setDuration(response.data.Data.duration)
|
||||
setName(response.data.widgetName)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
|
@ -361,7 +367,7 @@ const PieChartComponent = ({
|
|||
fetchSavedInputes();
|
||||
}
|
||||
}
|
||||
,[chartMeasurements, chartDuration])
|
||||
,[chartMeasurements, chartDuration, widgetName])
|
||||
|
||||
return <Pie data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
|
||||
};
|
||||
|
|
|
@ -1,22 +1,64 @@
|
|||
import { useMemo } from "react";
|
||||
import { Line, PolarArea } from "react-chartjs-2";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { PolarArea } from "react-chartjs-2";
|
||||
import io from "socket.io-client";
|
||||
import { useThemeStore } from "../../../../store/useThemeStore";
|
||||
import useChartStore from "../../../../store/useChartStore";
|
||||
import { useWidgetStore } from "../../../../store/useWidgetStore";
|
||||
import axios from "axios";
|
||||
|
||||
interface ChartComponentProps {
|
||||
id: string;
|
||||
type: any;
|
||||
title: string;
|
||||
fontFamily?: string;
|
||||
fontSize?: string;
|
||||
fontWeight?: "Light" | "Regular" | "Bold";
|
||||
data: any;
|
||||
}
|
||||
|
||||
const PolarAreaGraphComponent = ({
|
||||
id,
|
||||
type,
|
||||
title,
|
||||
fontFamily,
|
||||
fontSize,
|
||||
fontWeight = "Regular",
|
||||
}: ChartComponentProps) => {
|
||||
// Memoize Font Weight Mapping
|
||||
const { themeColor } = useThemeStore();
|
||||
const { measurements: chartMeasurements, duration: chartDuration, name: widgetName } = useChartStore();
|
||||
const [measurements, setmeasurements] = useState<any>({});
|
||||
const [duration, setDuration] = useState("1h")
|
||||
const [name, setName] = useState("Widget")
|
||||
const [chartData, setChartData] = useState<{ labels: string[]; datasets: any[] }>({
|
||||
labels: [],
|
||||
datasets: [],
|
||||
});
|
||||
const { selectedChartId } = useWidgetStore();
|
||||
|
||||
const iotApiUrl = process.env.REACT_APP_IOT_SOCKET_SERVER_URL;
|
||||
const email = localStorage.getItem("email") || "";
|
||||
const organization = email?.split("@")[1]?.split(".")[0]
|
||||
const defaultData = {
|
||||
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
|
||||
datasets: [
|
||||
{
|
||||
label: "Dataset",
|
||||
data: [12, 19, 3, 5, 2, 3],
|
||||
backgroundColor: ["#6f42c1"],
|
||||
borderColor: "#b392f0",
|
||||
borderWidth: 1,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
console.log("titleeeeeeeeeeeeeeeeeee",title);
|
||||
},[])
|
||||
|
||||
// Memoize Theme Colors
|
||||
const buttonActionColor = useMemo(() => themeColor[0] || "#5c87df", [themeColor]);
|
||||
const buttonAbortColor = useMemo(() => themeColor[1] || "#ffffff", [themeColor]);
|
||||
|
||||
// Memoize Font Styling
|
||||
const chartFontWeightMap = useMemo(
|
||||
() => ({
|
||||
Light: "lighter" as const,
|
||||
|
@ -26,19 +68,9 @@ const PolarAreaGraphComponent = ({
|
|||
[]
|
||||
);
|
||||
|
||||
// Parse and Memoize Font Size
|
||||
const fontSizeValue = useMemo(
|
||||
() => (fontSize ? parseInt(fontSize) : 12),
|
||||
[fontSize]
|
||||
);
|
||||
const fontSizeValue = useMemo(() => (fontSize ? parseInt(fontSize) : 12), [fontSize]);
|
||||
const fontWeightValue = useMemo(() => chartFontWeightMap[fontWeight], [fontWeight, chartFontWeightMap]);
|
||||
|
||||
// Determine and Memoize Font Weight
|
||||
const fontWeightValue = useMemo(
|
||||
() => chartFontWeightMap[fontWeight],
|
||||
[fontWeight, chartFontWeightMap]
|
||||
);
|
||||
|
||||
// Memoize Chart Font Style
|
||||
const chartFontStyle = useMemo(
|
||||
() => ({
|
||||
family: fontFamily || "Arial",
|
||||
|
@ -48,46 +80,110 @@ const PolarAreaGraphComponent = ({
|
|||
[fontFamily, fontSizeValue, fontWeightValue]
|
||||
);
|
||||
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: title,
|
||||
font: chartFontStyle,
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
ticks: {
|
||||
display: false, // This hides the x-axis labels
|
||||
// Memoize Chart Options
|
||||
const options = useMemo(
|
||||
() => ({
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
plugins: {
|
||||
title: {
|
||||
display: true,
|
||||
text: name,
|
||||
font: chartFontStyle,
|
||||
},
|
||||
legend: {
|
||||
display: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
[title, chartFontStyle]
|
||||
);
|
||||
scales: {
|
||||
// x: {
|
||||
// ticks: {
|
||||
// display: true, // This hides the x-axis labels
|
||||
// },
|
||||
// },
|
||||
},
|
||||
}),
|
||||
[title, chartFontStyle, name]
|
||||
);
|
||||
|
||||
const chartData = {
|
||||
labels: ["January", "February", "March", "April", "May", "June", "July"],
|
||||
datasets: [
|
||||
{
|
||||
label: "My First Dataset",
|
||||
data: [65, 59, 80, 81, 56, 55, 40],
|
||||
backgroundColor: "#6f42c1", // Updated to #6f42c1 (Purple)
|
||||
borderColor: "#ffffff", // Keeping border color white
|
||||
borderWidth: 2,
|
||||
fill: false,
|
||||
},
|
||||
],
|
||||
};
|
||||
// useEffect(() => {console.log(measurements);
|
||||
// },[measurements])
|
||||
|
||||
return <PolarArea data={chartData} options={options} />;
|
||||
useEffect(() => {
|
||||
if (!iotApiUrl || !measurements || Object.keys(measurements).length === 0) return;
|
||||
|
||||
const socket = io(`http://${iotApiUrl}`);
|
||||
|
||||
const inputData = {
|
||||
measurements,
|
||||
duration,
|
||||
interval: 1000,
|
||||
};
|
||||
|
||||
|
||||
const startStream = () => {
|
||||
socket.emit("lineInput", inputData);
|
||||
};
|
||||
|
||||
socket.on("connect", startStream);
|
||||
|
||||
socket.on("lineOutput", (response) => {
|
||||
const responseData = response.data;
|
||||
|
||||
// Extract timestamps and values
|
||||
const labels = responseData.time;
|
||||
const datasets = Object.keys(measurements).map((key) => {
|
||||
const measurement = measurements[key];
|
||||
const datasetKey = `${measurement.name}.${measurement.fields}`;
|
||||
return {
|
||||
label: datasetKey,
|
||||
data: responseData[datasetKey]?.values ?? [],
|
||||
backgroundColor: "#6f42c1",
|
||||
borderColor: "#b392f0",
|
||||
borderWidth: 1,
|
||||
};
|
||||
});
|
||||
|
||||
setChartData({ labels, datasets });
|
||||
});
|
||||
|
||||
return () => {
|
||||
socket.off("lineOutput");
|
||||
socket.emit("stop_stream"); // Stop streaming when component unmounts
|
||||
socket.disconnect();
|
||||
};
|
||||
}, [measurements, duration, iotApiUrl]);
|
||||
|
||||
const fetchSavedInputes = async() => {
|
||||
|
||||
if (id !== "") {
|
||||
try {
|
||||
const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}/api/v2/WidgetData/${id}/${organization}`);
|
||||
if (response.status === 200) {
|
||||
setmeasurements(response.data.Data.measurements)
|
||||
setDuration(response.data.Data.duration)
|
||||
setName(response.data.widgetName)
|
||||
} else {
|
||||
console.log("Unexpected response:", response);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("There was an error!", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchSavedInputes();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (selectedChartId?.id === id) {
|
||||
fetchSavedInputes();
|
||||
}
|
||||
}
|
||||
,[chartMeasurements, chartDuration, widgetName])
|
||||
|
||||
return <PolarArea data={Object.keys(measurements).length > 0 ? chartData : defaultData} options={options} />;
|
||||
};
|
||||
|
||||
export default PolarAreaGraphComponent;
|
||||
export default PolarAreaGraphComponent;
|
|
@ -0,0 +1,33 @@
|
|||
import React from 'react'
|
||||
|
||||
type Props = {}
|
||||
|
||||
const FleetEfficiencyComponent = ({
|
||||
object
|
||||
}: any) => {
|
||||
return (
|
||||
<>
|
||||
<h2 className="header">Fleet Efficiency</h2>
|
||||
<div className="progressContainer">
|
||||
<div className="progress">
|
||||
<div className="barOverflow">
|
||||
<div
|
||||
className="bar"
|
||||
style={{ transform: `rotate(${object.value}deg)` }}
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="scaleLabels">
|
||||
<span>0%</span>
|
||||
<div className="centerText">
|
||||
<div className="percentage">{object.per}%</div>
|
||||
<div className="status">Optimal</div>
|
||||
</div>
|
||||
<span>100%</span>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default FleetEfficiencyComponent
|
|
@ -0,0 +1,29 @@
|
|||
import React from 'react'
|
||||
import { WalletIcon } from '../../../icons/3dChartIcons'
|
||||
import { useWidgetStore } from '../../../../store/useWidgetStore';
|
||||
|
||||
const TotalCardComponent = ({
|
||||
object
|
||||
}: any) => {
|
||||
|
||||
const { setSelectedChartId } =
|
||||
useWidgetStore();
|
||||
return (
|
||||
<>
|
||||
<div className="header-wrapper" onClick={() => {
|
||||
setSelectedChartId(object.id)
|
||||
}}>
|
||||
<div className="header">{object.header}</div>
|
||||
<div className="data-values">
|
||||
<div className="value">{object.value}</div>
|
||||
<div className="per">{object.per}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="icon">
|
||||
<WalletIcon />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default TotalCardComponent
|
|
@ -0,0 +1,132 @@
|
|||
import React, { useState } from 'react'
|
||||
import { Line } from 'react-chartjs-2'
|
||||
import axios from 'axios';
|
||||
|
||||
const WarehouseThroughputComponent = ({
|
||||
object
|
||||
}: any) => {
|
||||
|
||||
const [measurements, setmeasurements] = useState<any>({});
|
||||
const [duration, setDuration] = useState("1h")
|
||||
|
||||
const lineGraphData = {
|
||||
labels: [
|
||||
"Jan",
|
||||
"Feb",
|
||||
"Mar",
|
||||
"Apr",
|
||||
"May",
|
||||
"Jun",
|
||||
"Jul",
|
||||
"Aug",
|
||||
"Sep",
|
||||
"Oct",
|
||||
"Nov",
|
||||
"Dec",
|
||||
], // Months of the year
|
||||
datasets: [
|
||||
{
|
||||
label: "Throughput (units/month)",
|
||||
data: [500, 400, 300, 450, 350, 250, 200, 300, 250, 150, 100, 150], // Example monthly data
|
||||
borderColor: "#6f42c1", // Use the desired color for the line (purple)
|
||||
backgroundColor: "rgba(111, 66, 193, 0.2)", // Use a semi-transparent purple for the fill
|
||||
borderWidth: 2, // Line thickness
|
||||
fill: true, // Enable fill for this dataset
|
||||
pointRadius: 0, // Remove dots at each data point
|
||||
tension: 0.5, // Smooth interpolation for the line
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Line graph options
|
||||
const lineGraphOptions = {
|
||||
responsive: true,
|
||||
maintainAspectRatio: false, // Allow custom height/width adjustments
|
||||
plugins: {
|
||||
legend: {
|
||||
display: false, // Hide legend
|
||||
},
|
||||
title: {
|
||||
display: false, // No chart title needed
|
||||
},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: (context: any) => {
|
||||
const value = context.parsed.y;
|
||||
return `${value} units`; // Customize tooltip to display "units"
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
x: {
|
||||
grid: {
|
||||
display: false, // Hide x-axis grid lines
|
||||
},
|
||||
ticks: {
|
||||
maxRotation: 0, // Prevent label rotation
|
||||
autoSkip: false, // Display all months
|
||||
font: {
|
||||
size: 8, // Adjust font size for readability
|
||||
color: "#ffffff", // Light text color for labels
|
||||
},
|
||||
},
|
||||
},
|
||||
y: {
|
||||
display: true, // Show y-axis
|
||||
grid: {
|
||||
drawBorder: false, // Remove border line
|
||||
color: "rgba(255, 255, 255, 0.2)", // Light gray color for grid lines
|
||||
borderDash: [5, 5], // Dotted line style (array defines dash and gap lengths)
|
||||
},
|
||||
ticks: {
|
||||
font: {
|
||||
size: 8, // Adjust font size for readability
|
||||
color: "#ffffff", // Light text color for ticks
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
elements: {
|
||||
line: {
|
||||
tension: 0.5, // Smooth interpolation for the line
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
// const fetchSavedInputes = async() => {
|
||||
|
||||
// if (object.id !== "") {
|
||||
// try {
|
||||
// const response = await axios.get(`http://${process.env.REACT_APP_SERVER_REST_API_LOCAL_BASE_URL}/api/v2/WidgetData/${id}/${organization}`);
|
||||
// if (response.status === 200) {
|
||||
// setmeasurements(response.data.Data.measurements)
|
||||
// setDuration(response.data.Data.duration)
|
||||
// setName(response.data.widgetName)
|
||||
// } else {
|
||||
// console.log("Unexpected response:", response);
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.error("There was an error!", error);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="header">
|
||||
<h2>Warehouse Throughput</h2>
|
||||
<p>
|
||||
<span>(+5) more</span> in 2025
|
||||
</p>
|
||||
</div>
|
||||
<div className="lineGraph" style={{ height: "100%" }}>
|
||||
<Line data={lineGraphData} options={lineGraphOptions} />
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default WarehouseThroughputComponent
|
|
@ -1,59 +1,59 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { getInitials } from "./functions/getInitials";
|
||||
import { getAvatarColor } from "./functions/getAvatarColor";
|
||||
|
||||
interface AvatarProps {
|
||||
name: string; // Name can be a full name or initials
|
||||
size?: number;
|
||||
index?: number;
|
||||
textColor?: string;
|
||||
}
|
||||
|
||||
const CustomAvatar: React.FC<AvatarProps> = ({
|
||||
name,
|
||||
size = 100,
|
||||
index = 0,
|
||||
textColor = "#ffffff",
|
||||
}) => {
|
||||
const [imageSrc, setImageSrc] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = document.createElement("canvas"); // Create an offscreen canvas
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (ctx) {
|
||||
const initials = getInitials(name); // Convert name to initials if needed
|
||||
|
||||
// Draw background
|
||||
ctx.fillStyle = getAvatarColor(index);
|
||||
ctx.fillRect(0, 0, size, size);
|
||||
|
||||
// Draw initials
|
||||
ctx.fillStyle = textColor;
|
||||
ctx.font = `bold ${size / 2}px Arial`;
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fillText(initials, size / 2, size / 2);
|
||||
|
||||
// Generate image source
|
||||
const dataURL = canvas.toDataURL("image/png");
|
||||
setImageSrc(dataURL);
|
||||
}
|
||||
}, [name, size, textColor]);
|
||||
|
||||
if (!imageSrc) {
|
||||
return null; // Return null while the image is being generated
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
className="user-image"
|
||||
src={imageSrc}
|
||||
alt="User Avatar"
|
||||
style={{ width: "100%", height: "100%" }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomAvatar;
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { getInitials } from "./functions/getInitials";
|
||||
import { getAvatarColor } from "./functions/getAvatarColor";
|
||||
|
||||
interface AvatarProps {
|
||||
name: string; // Name can be a full name or initials
|
||||
size?: number;
|
||||
index?: number;
|
||||
textColor?: string;
|
||||
}
|
||||
|
||||
const CustomAvatar: React.FC<AvatarProps> = ({
|
||||
name,
|
||||
size = 100,
|
||||
index = 0,
|
||||
textColor = "#ffffff",
|
||||
}) => {
|
||||
const [imageSrc, setImageSrc] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const canvas = document.createElement("canvas"); // Create an offscreen canvas
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
const ctx = canvas.getContext("2d");
|
||||
if (ctx) {
|
||||
const initials = getInitials(name); // Convert name to initials if needed
|
||||
|
||||
// Draw background
|
||||
ctx.fillStyle = getAvatarColor(index);
|
||||
ctx.fillRect(0, 0, size, size);
|
||||
|
||||
// Draw initials
|
||||
ctx.fillStyle = textColor;
|
||||
ctx.font = `bold ${size / 2}px Arial`;
|
||||
ctx.textAlign = "center";
|
||||
ctx.textBaseline = "middle";
|
||||
ctx.fillText(initials, size / 2, size / 2);
|
||||
|
||||
// Generate image source
|
||||
const dataURL = canvas.toDataURL("image/png");
|
||||
setImageSrc(dataURL);
|
||||
}
|
||||
}, [name, size, textColor]);
|
||||
|
||||
if (!imageSrc) {
|
||||
return null; // Return null while the image is being generated
|
||||
}
|
||||
|
||||
return (
|
||||
<img
|
||||
className="user-image"
|
||||
src={imageSrc}
|
||||
alt="User Avatar"
|
||||
style={{ width: "100%", height: "100%" }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default CustomAvatar;
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
const avatarColors: string[] = [
|
||||
"#FF5733", // Red Orange
|
||||
"#48ac2a", // Leaf Green
|
||||
"#0050eb", // Royal Blue
|
||||
"#FF33A1", // Hot Pink
|
||||
"#FF8C33", // Deep Orange
|
||||
"#8C33FF", // Violet
|
||||
"#FF3333", // Bright Red
|
||||
"#43c06d", // Emerald Green
|
||||
"#A133FF", // Amethyst Purple
|
||||
"#C70039", // Crimson
|
||||
"#900C3F", // Maroon
|
||||
"#581845", // Plum
|
||||
"#3498DB", // Sky Blue
|
||||
"#2ECC71", // Green Mint
|
||||
"#E74C3C", // Tomato Red
|
||||
"#00adff", // Azure
|
||||
"#DBAD05", // Amber Yellow
|
||||
"#FF5733", // Red Orange
|
||||
"#FF33A1", // Hot Pink
|
||||
"#900C3F", // Maroon
|
||||
];
|
||||
|
||||
export function getAvatarColor(index: number): string {
|
||||
return avatarColors[index % avatarColors.length];
|
||||
}
|
||||
const avatarColors: string[] = [
|
||||
"#FF5733", // Red Orange
|
||||
"#48ac2a", // Leaf Green
|
||||
"#0050eb", // Royal Blue
|
||||
"#FF33A1", // Hot Pink
|
||||
"#FF8C33", // Deep Orange
|
||||
"#8C33FF", // Violet
|
||||
"#FF3333", // Bright Red
|
||||
"#43c06d", // Emerald Green
|
||||
"#A133FF", // Amethyst Purple
|
||||
"#C70039", // Crimson
|
||||
"#900C3F", // Maroon
|
||||
"#581845", // Plum
|
||||
"#3498DB", // Sky Blue
|
||||
"#2ECC71", // Green Mint
|
||||
"#E74C3C", // Tomato Red
|
||||
"#00adff", // Azure
|
||||
"#DBAD05", // Amber Yellow
|
||||
"#FF5733", // Red Orange
|
||||
"#FF33A1", // Hot Pink
|
||||
"#900C3F", // Maroon
|
||||
];
|
||||
|
||||
export function getAvatarColor(index: number): string {
|
||||
return avatarColors[index % avatarColors.length];
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
export const getInitials = (fullName: string): string => {
|
||||
// Extract initials from the name
|
||||
const words = fullName.split(" ");
|
||||
const initials = words
|
||||
.map((word) => word[0])
|
||||
.slice(0, 2)
|
||||
.join("")
|
||||
.toUpperCase();
|
||||
return initials;
|
||||
export const getInitials = (fullName: string): string => {
|
||||
// Extract initials from the name
|
||||
const words = fullName.split(" ");
|
||||
const initials = words
|
||||
.map((word) => word[0])
|
||||
.slice(0, 2)
|
||||
.join("")
|
||||
.toUpperCase();
|
||||
return initials;
|
||||
};
|
|
@ -1,4 +1,5 @@
|
|||
let url_Backend_dwinzo = `http://${process.env.REACT_APP_SERVER_REST_API_BASE_URL}`;
|
||||
console.log("url_Backend_dwinzo: ", url_Backend_dwinzo);
|
||||
|
||||
export const getSelect2dZoneData = async (
|
||||
ZoneId?: string,
|
||||
|
|
|
@ -14,7 +14,6 @@ export const getZoneData = async (zoneId: string, organization: string) => {
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to fetch zoneData");
|
||||
}
|
||||
|
|
|
@ -9,20 +9,26 @@ interface MeasurementStore {
|
|||
measurements: Record<string, Measurement>; // Change array to Record<string, Measurement>
|
||||
interval: number;
|
||||
duration: string;
|
||||
name: string;
|
||||
setMeasurements: (newMeasurements: Record<string, Measurement>) => void;
|
||||
updateDuration: (newDuration: string) => void;
|
||||
updateName: (newName: string) => void;
|
||||
}
|
||||
|
||||
const useChartStore = create<MeasurementStore>((set) => ({
|
||||
measurements: {}, // Initialize as an empty object
|
||||
interval: 1000,
|
||||
duration: "1h",
|
||||
name:'',
|
||||
|
||||
setMeasurements: (newMeasurements) =>
|
||||
set(() => ({ measurements: newMeasurements })),
|
||||
|
||||
updateDuration: (newDuration) =>
|
||||
set(() => ({ duration: newDuration })),
|
||||
|
||||
updateName: (newName) =>
|
||||
set(() => ({ duration: newName })),
|
||||
}));
|
||||
|
||||
export default useChartStore;
|
||||
|
|
|
@ -33,7 +33,7 @@ interface WidgetStore {
|
|||
setDraggedAsset: (asset: Widget | null) => void; // Setter for draggedAsset
|
||||
addWidget: (widget: Widget) => void; // Add a new widget
|
||||
setWidgets: (widgets: Widget[]) => void; // Replace the entire widgets array
|
||||
setSelectedChartId: (widget: Widget | null) => void; // Set the selected chart/widget
|
||||
setSelectedChartId: (widget: any | null) => void; // Set the selected chart/widget
|
||||
}
|
||||
|
||||
// Create the store with Zustand
|
||||
|
|
|
@ -318,6 +318,25 @@
|
|||
|
||||
.sidebar-right-content-container {
|
||||
.dataSideBar {
|
||||
.inputs-wrapper {
|
||||
.datas {
|
||||
|
||||
.input-value {
|
||||
|
||||
padding: 5px 10px;
|
||||
}
|
||||
|
||||
.input-value,
|
||||
.rename-input {
|
||||
margin-right: 24px;
|
||||
width: 170px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
|
@ -991,11 +1010,9 @@
|
|||
top: 50%;
|
||||
right: -10px;
|
||||
transform: translate(0, -50%);
|
||||
background: linear-gradient(
|
||||
144.19deg,
|
||||
#f1e7cd 16.62%,
|
||||
#fffaef 85.81%
|
||||
);
|
||||
background: linear-gradient(144.19deg,
|
||||
#f1e7cd 16.62%,
|
||||
#fffaef 85.81%);
|
||||
}
|
||||
|
||||
.category-image {
|
||||
|
@ -1058,4 +1075,4 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,221 +1,221 @@
|
|||
@use "../abstracts/variables.scss" as *;
|
||||
@use "../abstracts/mixins.scss" as *;
|
||||
|
||||
.dashboard-main {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
.side-pannel-container {
|
||||
padding: 32px;
|
||||
min-width: 240px;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
border-right: 1px solid var(--border-color);
|
||||
.side-pannel-header {
|
||||
@include flex-space-between;
|
||||
.user-container {
|
||||
@include flex-center;
|
||||
gap: 6px;
|
||||
.user-profile {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
font-weight: var(--font-weight-medium);
|
||||
background: var(--accent-color);
|
||||
color: var(--primary-color);
|
||||
border-radius: #{$border-radius-circle};
|
||||
}
|
||||
.user-name {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
}
|
||||
.notifications-container {
|
||||
@include flex-center;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.new-project-button {
|
||||
padding: 12px 16px;
|
||||
cursor: not-allowed;
|
||||
color: var(--accent-color);
|
||||
background-color: var(--background-color-secondary);
|
||||
border-radius: #{$border-radius-large};
|
||||
}
|
||||
.side-bar-content-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
.side-bar-options-container {
|
||||
.option-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 10px;
|
||||
margin: 4px 0;
|
||||
border-radius: #{$border-radius-medium};
|
||||
&:hover {
|
||||
background: var(--background-color-secondary);
|
||||
}
|
||||
}
|
||||
.active {
|
||||
color: var(--accent-color);
|
||||
font-weight: var(--font-weight-medium);
|
||||
background-color: var(--highlight-accent-color);
|
||||
&:hover {
|
||||
background-color: var(--highlight-accent-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.dashboard-home-container {
|
||||
width: 100%;
|
||||
.dashboard-navbar-container {
|
||||
margin-top: 28px;
|
||||
padding: 8px 34px 8px 12px;
|
||||
@include flex-center;
|
||||
.title {
|
||||
text-transform: capitalize;
|
||||
font-size: var(--font-size-large);
|
||||
width: 100%;
|
||||
}
|
||||
.market-place-button {
|
||||
@include flex-center;
|
||||
gap: 6px;
|
||||
padding: 8px 14px;
|
||||
background: var(--accent-gradient-color);
|
||||
white-space: nowrap;
|
||||
border-radius: #{$border-radius-large};
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.search-wrapper {
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
.container {
|
||||
margin: 22px 0;
|
||||
width: 100%;
|
||||
padding: 0 12px;
|
||||
.header {
|
||||
font-size: var(--font-size-large);
|
||||
}
|
||||
.cards-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
gap: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-card-container {
|
||||
height: 242px;
|
||||
width: calc((100% / 5) - 23px);
|
||||
min-width: 260px;
|
||||
position: relative;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: #{$border-radius-large};
|
||||
overflow: hidden;
|
||||
.preview-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
vertical-align: top;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
.project-details-container {
|
||||
@include flex-space-between;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 8px 16px;
|
||||
background: var(--primary-color);
|
||||
border-radius: 10px;
|
||||
.project-details {
|
||||
.project-name {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.project-data {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
}
|
||||
.users-list-container {
|
||||
@include flex-center;
|
||||
gap: 6px;
|
||||
.user-profile {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
background-color: var(--accent-color);
|
||||
color: var(--primary-color);
|
||||
border-radius: #{$border-radius-circle};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.market-place-banner-container {
|
||||
width: 100%;
|
||||
height: 230px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
padding: 0 24px;
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 30px;
|
||||
}
|
||||
.hero-text {
|
||||
position: absolute;
|
||||
left: 52px;
|
||||
bottom: 25px;
|
||||
font-size: 48px;
|
||||
font-family: #{$font-roboto};
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.context {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 58px;
|
||||
text-transform: uppercase;
|
||||
font-size: 22px;
|
||||
width: 300px;
|
||||
color: #ffffff;
|
||||
font-family: #{$font-roboto};
|
||||
}
|
||||
.arrow-context {
|
||||
position: absolute;
|
||||
bottom: 27px;
|
||||
right: 300px;
|
||||
}
|
||||
.explore-button {
|
||||
position: absolute;
|
||||
top: 95px;
|
||||
right: 52px;
|
||||
padding: 10px 20px;
|
||||
text-transform: uppercase;
|
||||
font-size: 24px;
|
||||
border: 1px solid #ffffff;
|
||||
color: #ffffff;
|
||||
font-family: #{$font-roboto};
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
@use "../abstracts/variables.scss" as *;
|
||||
@use "../abstracts/mixins.scss" as *;
|
||||
|
||||
.dashboard-main {
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
display: flex;
|
||||
.side-pannel-container {
|
||||
padding: 32px;
|
||||
min-width: 240px;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
border-right: 1px solid var(--border-color);
|
||||
.side-pannel-header {
|
||||
@include flex-space-between;
|
||||
.user-container {
|
||||
@include flex-center;
|
||||
gap: 6px;
|
||||
.user-profile {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
line-height: 32px;
|
||||
text-align: center;
|
||||
font-weight: var(--font-weight-medium);
|
||||
background: var(--accent-color);
|
||||
color: var(--primary-color);
|
||||
border-radius: #{$border-radius-circle};
|
||||
}
|
||||
.user-name {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
}
|
||||
.notifications-container {
|
||||
@include flex-center;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
.new-project-button {
|
||||
padding: 12px 16px;
|
||||
cursor: not-allowed;
|
||||
color: var(--accent-color);
|
||||
background-color: var(--background-color-secondary);
|
||||
border-radius: #{$border-radius-large};
|
||||
}
|
||||
.side-bar-content-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
.side-bar-options-container {
|
||||
.option-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 6px 10px;
|
||||
margin: 4px 0;
|
||||
border-radius: #{$border-radius-medium};
|
||||
&:hover {
|
||||
background: var(--background-color-secondary);
|
||||
}
|
||||
}
|
||||
.active {
|
||||
color: var(--accent-color);
|
||||
font-weight: var(--font-weight-medium);
|
||||
background-color: var(--highlight-accent-color);
|
||||
&:hover {
|
||||
background-color: var(--highlight-accent-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.dashboard-home-container {
|
||||
width: 100%;
|
||||
.dashboard-navbar-container {
|
||||
margin-top: 28px;
|
||||
padding: 8px 34px 8px 12px;
|
||||
@include flex-center;
|
||||
.title {
|
||||
text-transform: capitalize;
|
||||
font-size: var(--font-size-large);
|
||||
width: 100%;
|
||||
}
|
||||
.market-place-button {
|
||||
@include flex-center;
|
||||
gap: 6px;
|
||||
padding: 8px 14px;
|
||||
background: var(--accent-gradient-color);
|
||||
white-space: nowrap;
|
||||
border-radius: #{$border-radius-large};
|
||||
color: var(--primary-color);
|
||||
}
|
||||
.search-wrapper {
|
||||
width: 400px;
|
||||
}
|
||||
}
|
||||
.container {
|
||||
margin: 22px 0;
|
||||
width: 100%;
|
||||
padding: 0 12px;
|
||||
.header {
|
||||
font-size: var(--font-size-large);
|
||||
}
|
||||
.cards-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
gap: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dashboard-card-container {
|
||||
height: 242px;
|
||||
width: calc((100% / 5) - 23px);
|
||||
min-width: 260px;
|
||||
position: relative;
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: #{$border-radius-large};
|
||||
overflow: hidden;
|
||||
.preview-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
vertical-align: top;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
.project-details-container {
|
||||
@include flex-space-between;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: 8px 16px;
|
||||
background: var(--primary-color);
|
||||
border-radius: 10px;
|
||||
.project-details {
|
||||
.project-name {
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.project-data {
|
||||
color: var(--accent-color);
|
||||
}
|
||||
}
|
||||
.users-list-container {
|
||||
@include flex-center;
|
||||
gap: 6px;
|
||||
.user-profile {
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
line-height: 26px;
|
||||
text-align: center;
|
||||
background-color: var(--accent-color);
|
||||
color: var(--primary-color);
|
||||
border-radius: #{$border-radius-circle};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.market-place-banner-container {
|
||||
width: 100%;
|
||||
height: 230px;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
padding: 0 24px;
|
||||
img {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
border-radius: 30px;
|
||||
}
|
||||
.hero-text {
|
||||
position: absolute;
|
||||
left: 52px;
|
||||
bottom: 25px;
|
||||
font-size: 48px;
|
||||
font-family: #{$font-roboto};
|
||||
font-weight: 800;
|
||||
color: #ffffff;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
.context {
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
right: 58px;
|
||||
text-transform: uppercase;
|
||||
font-size: 22px;
|
||||
width: 300px;
|
||||
color: #ffffff;
|
||||
font-family: #{$font-roboto};
|
||||
}
|
||||
.arrow-context {
|
||||
position: absolute;
|
||||
bottom: 27px;
|
||||
right: 300px;
|
||||
}
|
||||
.explore-button {
|
||||
position: absolute;
|
||||
top: 95px;
|
||||
right: 52px;
|
||||
padding: 10px 20px;
|
||||
text-transform: uppercase;
|
||||
font-size: 24px;
|
||||
border: 1px solid #ffffff;
|
||||
color: #ffffff;
|
||||
font-family: #{$font-roboto};
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue