From f7f11907dc6a7e63bebd0fa7e617585e809a583f Mon Sep 17 00:00:00 2001 From: Fachba Date: Tue, 21 Oct 2025 13:01:37 +0700 Subject: [PATCH] add menu dashboard svg --- src/App.jsx | 17 +++ src/layout/LayoutMenu.jsx | 63 +++++++- src/pages/home/SvgAirDryerA.jsx | 20 +++ src/pages/home/SvgAirDryerB.jsx | 20 +++ src/pages/home/SvgAirDryerC.jsx | 20 +++ src/pages/home/SvgCompressorA.jsx | 20 +++ src/pages/home/SvgCompressorB.jsx | 20 +++ src/pages/home/SvgCompressorC.jsx | 20 +++ src/pages/home/SvgOverview.jsx | 20 +++ src/pages/home/SvgTemplate.jsx | 19 +++ src/pages/home/SvgTest.jsx | 1 + src/pages/home/SvgViewer.jsx | 19 +++ svg/air_dryer_A_rev.svg | 238 ++++++++++++++++++++++++++++++ svg/air_dryer_B_rev.svg | 238 ++++++++++++++++++++++++++++++ svg/air_dryer_C_rev.svg | 238 ++++++++++++++++++++++++++++++ 15 files changed, 968 insertions(+), 5 deletions(-) create mode 100644 src/pages/home/SvgAirDryerA.jsx create mode 100644 src/pages/home/SvgAirDryerB.jsx create mode 100644 src/pages/home/SvgAirDryerC.jsx create mode 100644 src/pages/home/SvgCompressorA.jsx create mode 100644 src/pages/home/SvgCompressorB.jsx create mode 100644 src/pages/home/SvgCompressorC.jsx create mode 100644 src/pages/home/SvgOverview.jsx create mode 100644 src/pages/home/SvgTemplate.jsx create mode 100644 src/pages/home/SvgViewer.jsx create mode 100644 svg/air_dryer_A_rev.svg create mode 100644 svg/air_dryer_B_rev.svg create mode 100644 svg/air_dryer_C_rev.svg diff --git a/src/App.jsx b/src/App.jsx index 511886c..31dfb1d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -35,6 +35,13 @@ import IndexUser from './pages/user/IndexUser'; import IndexMember from './pages/shiftManagement/member/IndexMember'; import SvgTest from './pages/home/SvgTest'; +import SvgOverview from './pages/home/SvgOverview'; +import SvgCompressorA from './pages/home/SvgCompressorA'; +import SvgCompressorB from './pages/home/SvgCompressorB'; +import SvgCompressorC from './pages/home/SvgCompressorC'; +import SvgAirDryerA from './pages/home/SvgAirDryerA'; +import SvgAirDryerB from './pages/home/SvgAirDryerB'; +import SvgAirDryerC from './pages/home/SvgAirDryerC'; const App = () => { return ( @@ -52,6 +59,16 @@ const App = () => { } /> + }> + } /> + } /> + } /> + } /> + } /> + } /> + } /> + + }> } /> } /> diff --git a/src/layout/LayoutMenu.jsx b/src/layout/LayoutMenu.jsx index 6e0bc57..e3c9d62 100644 --- a/src/layout/LayoutMenu.jsx +++ b/src/layout/LayoutMenu.jsx @@ -26,6 +26,9 @@ import { TeamOutlined, ClockCircleOutlined, CalendarOutlined, + DesktopOutlined, + NodeExpandOutlined, + GroupOutlined, } from '@ant-design/icons'; const { Text } = Typography; @@ -40,6 +43,48 @@ const allItems = [ ), }, + { + key: 'dashboard-svg', + icon: , + label: 'Dashboard', + children: [ + { + key: 'dashboard-svg-overview', + icon: , + label: Overview, + }, + { + key: 'dashboard-svg-compressor-a', + icon: , + label: Compressor A, + }, + { + key: 'dashboard-svg-compressor-b', + icon: , + label: Compressor B, + }, + { + key: 'dashboard-svg-compressor-c', + icon: , + label: Compressor C, + }, + { + key: 'dashboard-svg-airdryer-a', + icon: , + label: Air Dryer A, + }, + { + key: 'dashboard-svg-airdryer-b', + icon: , + label: Air Dryer B, + }, + { + key: 'dashboard-svg-airdryer-c', + icon: , + label: Air Dryer C, + }, + ], + }, { key: 'master', icon: , @@ -60,16 +105,16 @@ const allItems = [ icon: , label: Device, }, - { - key: 'master-tag', - icon: , - label: Tag, - }, { key: 'master-unit', icon: , label: Unit, }, + { + key: 'master-tag', + icon: , + label: Tag, + }, { key: 'master-status', icon: , @@ -163,6 +208,7 @@ const LayoutMenu = () => { if (pathname === '/notification') return 'notification'; if (pathname === '/event-alarm') return 'event-alarm'; if (pathname === '/jadwal-shift') return 'jadwal-shift'; + if (pathname === '/dashboard-svg') return 'dashboard-svg'; // Handle master routes if (pathname.startsWith('/master/')) { @@ -170,6 +216,12 @@ const LayoutMenu = () => { return `master-${subPath}`; } + // Handle master routes + if (pathname.startsWith('/dashboard-svg/')) { + const subPath = pathParts[1]; + return `dashboard-svg-${subPath}`; + } + // Handle history routes if (pathname.startsWith('/history/')) { const subPath = pathParts[1]; @@ -188,6 +240,7 @@ const LayoutMenu = () => { // Function to get parent key from menu key const getParentKey = (key) => { if (key.startsWith('master-')) return 'master'; + if (key.startsWith('dashboard-svg-')) return 'dashboard-svg'; if (key.startsWith('history-')) return 'history'; if (key.startsWith('shift-')) return 'shift-management'; return null; diff --git a/src/pages/home/SvgAirDryerA.jsx b/src/pages/home/SvgAirDryerA.jsx new file mode 100644 index 0000000..37f07a3 --- /dev/null +++ b/src/pages/home/SvgAirDryerA.jsx @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react'; +import { Card, Typography, Flex } from 'antd'; +import { setValSvg } from '../../components/Global/MqttConnection'; +import SvgTemplate from './SvgTemplate'; +import SvgViewer from './SvgViewer'; + +const { Text } = Typography; + +const filePathSvg = '/svg/air_dryer_A_rev.svg'; +const topicMqtt = 'PIU_GGCP/Devices/PB'; + +const SvgAirDryerA = () => { + return ( + + + + ); +}; + +export default SvgAirDryerA; diff --git a/src/pages/home/SvgAirDryerB.jsx b/src/pages/home/SvgAirDryerB.jsx new file mode 100644 index 0000000..6250cea --- /dev/null +++ b/src/pages/home/SvgAirDryerB.jsx @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react'; +import { Card, Typography, Flex } from 'antd'; +import { setValSvg } from '../../components/Global/MqttConnection'; +import SvgTemplate from './SvgTemplate'; +import SvgViewer from './SvgViewer'; + +const { Text } = Typography; + +const filePathSvg = '/svg/air_dryer_B_rev.svg'; +const topicMqtt = 'PIU_GGCP/Devices/PB'; + +const SvgAirDryerB = () => { + return ( + + + + ); +}; + +export default SvgAirDryerB; diff --git a/src/pages/home/SvgAirDryerC.jsx b/src/pages/home/SvgAirDryerC.jsx new file mode 100644 index 0000000..cdb61ce --- /dev/null +++ b/src/pages/home/SvgAirDryerC.jsx @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react'; +import { Card, Typography, Flex } from 'antd'; +import { setValSvg } from '../../components/Global/MqttConnection'; +import SvgTemplate from './SvgTemplate'; +import SvgViewer from './SvgViewer'; + +const { Text } = Typography; + +const filePathSvg = '/svg/air_dryer_C_rev.svg'; +const topicMqtt = 'PIU_GGCP/Devices/PB'; + +const SvgAirDryerC = () => { + return ( + + + + ); +}; + +export default SvgAirDryerC; diff --git a/src/pages/home/SvgCompressorA.jsx b/src/pages/home/SvgCompressorA.jsx new file mode 100644 index 0000000..bc7ffd2 --- /dev/null +++ b/src/pages/home/SvgCompressorA.jsx @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react'; +import { Card, Typography, Flex } from 'antd'; +import { setValSvg } from '../../components/Global/MqttConnection'; +import SvgTemplate from './SvgTemplate'; +import SvgViewer from './SvgViewer'; + +const { Text } = Typography; + +const filePathSvg = '/svg/test-new.svg'; +const topicMqtt = 'PIU_GGCP/Devices/PB'; + +const SvgCompressorA = () => { + return ( + + + + ); +}; + +export default SvgCompressorA; diff --git a/src/pages/home/SvgCompressorB.jsx b/src/pages/home/SvgCompressorB.jsx new file mode 100644 index 0000000..fbf5871 --- /dev/null +++ b/src/pages/home/SvgCompressorB.jsx @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react'; +import { Card, Typography, Flex } from 'antd'; +import { setValSvg } from '../../components/Global/MqttConnection'; +import SvgTemplate from './SvgTemplate'; +import SvgViewer from './SvgViewer'; + +const { Text } = Typography; + +const filePathSvg = '/svg/test-new.svg'; +const topicMqtt = 'PIU_GGCP/Devices/PB'; + +const SvgCompressorB = () => { + return ( + + + + ); +}; + +export default SvgCompressorB; diff --git a/src/pages/home/SvgCompressorC.jsx b/src/pages/home/SvgCompressorC.jsx new file mode 100644 index 0000000..0983260 --- /dev/null +++ b/src/pages/home/SvgCompressorC.jsx @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react'; +import { Card, Typography, Flex } from 'antd'; +import { setValSvg } from '../../components/Global/MqttConnection'; +import SvgTemplate from './SvgTemplate'; +import SvgViewer from './SvgViewer'; + +const { Text } = Typography; + +const filePathSvg = '/svg/test-new.svg'; +const topicMqtt = 'PIU_GGCP/Devices/PB'; + +const SvgCompressorC = () => { + return ( + + + + ); +}; + +export default SvgCompressorC; diff --git a/src/pages/home/SvgOverview.jsx b/src/pages/home/SvgOverview.jsx new file mode 100644 index 0000000..d5b432d --- /dev/null +++ b/src/pages/home/SvgOverview.jsx @@ -0,0 +1,20 @@ +import { useEffect, useState } from 'react'; +import { Card, Typography, Flex } from 'antd'; +import { setValSvg } from '../../components/Global/MqttConnection'; +import SvgTemplate from './SvgTemplate'; +import SvgViewer from './SvgViewer'; + +const { Text } = Typography; + +const filePathSvg = '/svg/test-new.svg'; +const topicMqtt = 'PIU_GGCP/Devices/PB'; + +const SvgOverview = () => { + return ( + + + + ); +}; + +export default SvgOverview; diff --git a/src/pages/home/SvgTemplate.jsx b/src/pages/home/SvgTemplate.jsx new file mode 100644 index 0000000..da2a702 --- /dev/null +++ b/src/pages/home/SvgTemplate.jsx @@ -0,0 +1,19 @@ +const SvgTemplate = ({ children }) => { + return ( +
+ {children} +
+ ); +}; + +export default SvgTemplate; diff --git a/src/pages/home/SvgTest.jsx b/src/pages/home/SvgTest.jsx index 1b65a69..87d8beb 100644 --- a/src/pages/home/SvgTest.jsx +++ b/src/pages/home/SvgTest.jsx @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'; import { Card, Typography, Flex } from 'antd'; // import { ReactSVG } from 'react-svg'; import { setValSvg } from '../../components/Global/MqttConnection'; +import { ReactSVG } from 'react-svg'; const { Text } = Typography; diff --git a/src/pages/home/SvgViewer.jsx b/src/pages/home/SvgViewer.jsx new file mode 100644 index 0000000..242f012 --- /dev/null +++ b/src/pages/home/SvgViewer.jsx @@ -0,0 +1,19 @@ +// SvgViewer.jsx +import { ReactSVG } from 'react-svg'; + +const SvgViewer = ({ filePathSvg, topicMqtt, setValSvg }) => { + return ( + { + svg.setAttribute('width', '100%'); + svg.setAttribute('height', '100%'); + svg.setAttribute('preserveAspectRatio', 'xMidYMid meet'); + if (setValSvg) setValSvg(topicMqtt, svg); + }} + style={{ width: '100%', height: '100%' }} + /> + ); +}; + +export default SvgViewer; diff --git a/svg/air_dryer_A_rev.svg b/svg/air_dryer_A_rev.svg new file mode 100644 index 0000000..53876ed --- /dev/null +++ b/svg/air_dryer_A_rev.svg @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Heater Temp SP + + ####.## + °F + + Heater Temp + + ####.## + °F + + Heater Temp + + ####.## + °F + HEATER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dew Temp + + ####.## + °C + + Dew Temp + + ####.## + °F + AIROUTLET + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AIRINLET + + + + + + + + + + + + + + + + + + + + + + + + + RUN HOUR + + ####.## + H + + PURGE HOUR + + ####.## + H + + HEATER HOUR + + ####.## + H + + Alarm Info + + ####.## + H + + RT or LT Dry + + LT Dry + RT Dry + + Opmode + + HTD + + Step + ####.## + s + + Cycle Timer + + ####.## + s + Time + ## + + Dryer Status + + + + Shutdown + + + + Alarm Status + + + REGEN + + DRYING + + REGEN + + DRYING + + AIR DRYER UNIT A (01-CL-10532-A) + \ No newline at end of file diff --git a/svg/air_dryer_B_rev.svg b/svg/air_dryer_B_rev.svg new file mode 100644 index 0000000..4dff501 --- /dev/null +++ b/svg/air_dryer_B_rev.svg @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Heater Temp SP + + ####.## + °F + + Heater Temp + + ####.## + °F + + Heater Temp + + ####.## + °F + HEATER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dew Temp + + ####.## + °C + + Dew Temp + + ####.## + °F + AIROUTLET + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AIRINLET + + + + + + + + + + + + + + + + + + + + + + + + + RUN HOUR + + ####.## + H + + PURGE HOUR + + ####.## + H + + HEATER HOUR + + ####.## + H + + Alarm Info + + ####.## + H + + RT or LT Dry + + LT Dry + RT Dry + + Opmode + + HTD + + Step + ####.## + s + + Cycle Timer + + ####.## + s + Time + ## + + Dryer Status + + + + Shutdown + + + + Alarm Status + + + REGEN + + DRYING + + REGEN + + DRYING + + AIR DRYER UNIT B (01-CL-10535-B) + \ No newline at end of file diff --git a/svg/air_dryer_C_rev.svg b/svg/air_dryer_C_rev.svg new file mode 100644 index 0000000..3c13ba1 --- /dev/null +++ b/svg/air_dryer_C_rev.svg @@ -0,0 +1,238 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Heater Temp SP + + ####.## + °F + + Heater Temp + + ####.## + °F + + Heater Temp + + ####.## + °F + HEATER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Dew Temp + + ####.## + °C + + Dew Temp + + ####.## + °F + AIROUTLET + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AIRINLET + + + + + + + + + + + + + + + + + + + + + + + + + RUN HOUR + + ####.## + H + + PURGE HOUR + + ####.## + H + + HEATER HOUR + + ####.## + H + + Alarm Info + + ####.## + H + + RT or LT Dry + + LT Dry + RT Dry + + Opmode + + HTD + + Step + ####.## + s + + Cycle Timer + + ####.## + s + Time + ## + + Dryer Status + + + + Shutdown + + + + Alarm Status + + + REGEN + + DRYING + + REGEN + + DRYING + + AIR DRYER UNIT C (01-CL-10539-C) + \ No newline at end of file