diff --git a/src/components/Dashboard/common/MinMaxDisplay.jsx b/src/components/Dashboard/common/MinMaxDisplay.jsx
new file mode 100644
index 0000000..6bfd647
--- /dev/null
+++ b/src/components/Dashboard/common/MinMaxDisplay.jsx
@@ -0,0 +1,66 @@
+import { Flex, Typography, Tag, Space } from 'antd'
+import PropTypes from 'prop-types'
+
+const { Text } = Typography
+
+const getPrecision = (step) => {
+ if (step == null) return null
+ const stepStr = String(step)
+ const dotIndex = stepStr.indexOf('.')
+ return dotIndex === -1 ? 0 : stepStr.length - dotIndex - 1
+}
+
+const formatValue = (value, step) => {
+ if (value == null || value === '') return null
+ const parsed = parseFloat(value)
+ if (Number.isNaN(parsed)) return null
+
+ const precision = getPrecision(step)
+ return precision == null ? parsed.toString() : parsed.toFixed(precision)
+}
+
+const MinMaxDisplay = ({ value, prefix = '', suffix = '', step }) => {
+ const min = formatValue(value?.min, step)
+ const max = formatValue(value?.max, step)
+
+ return (
+
+
+
+ {min != null ? (
+ prefix + min + suffix
+ ) : (
+ n/a
+ )}
+
+
+ Min
+
+
+
+
+ {max != null ? (
+ prefix + max + suffix
+ ) : (
+ n/a
+ )}
+
+
+ Max
+
+
+
+ )
+}
+
+MinMaxDisplay.propTypes = {
+ value: PropTypes.shape({
+ min: PropTypes.number,
+ max: PropTypes.number
+ }),
+ prefix: PropTypes.string,
+ suffix: PropTypes.string,
+ step: PropTypes.number
+}
+
+export default MinMaxDisplay
diff --git a/src/components/Dashboard/common/MinMaxInput.jsx b/src/components/Dashboard/common/MinMaxInput.jsx
new file mode 100644
index 0000000..d4da401
--- /dev/null
+++ b/src/components/Dashboard/common/MinMaxInput.jsx
@@ -0,0 +1,65 @@
+import { Flex, InputNumber, Typography } from 'antd'
+import PropTypes from 'prop-types'
+
+const { Text } = Typography
+
+const MinMaxInput = ({
+ value = {},
+ onChange,
+ prefix = '',
+ suffix = '',
+ min,
+ max,
+ step,
+ disabled = false
+}) => {
+ const handleChange = (field, val) => {
+ if (!onChange) return
+ onChange({ ...value, [field]: val })
+ }
+
+ return (
+
+ Min:}
+ value={value?.min}
+ onChange={(val) => handleChange('min', val)}
+ prefix={prefix}
+ suffix={suffix}
+ min={min}
+ max={max}
+ step={step}
+ disabled={disabled}
+ style={{ minWidth: 120, flex: 1 }}
+ />
+ Max:}
+ value={value?.max}
+ onChange={(val) => handleChange('max', val)}
+ prefix={prefix}
+ suffix={suffix}
+ min={min}
+ max={max}
+ step={step}
+ disabled={disabled}
+ style={{ minWidth: 120, flex: 1 }}
+ />
+
+ )
+}
+
+MinMaxInput.propTypes = {
+ value: PropTypes.shape({
+ min: PropTypes.number,
+ max: PropTypes.number
+ }),
+ onChange: PropTypes.func,
+ prefix: PropTypes.string,
+ suffix: PropTypes.string,
+ min: PropTypes.number,
+ max: PropTypes.number,
+ step: PropTypes.number,
+ disabled: PropTypes.bool
+}
+
+export default MinMaxInput