Update NumericInput size and decimal digits
This commit is contained in:
@@ -15,7 +15,7 @@ const DeviationList = ({
|
||||
<div className="bg-amber-50 p-5 rounded-lg shadow-sm border border-amber-200">
|
||||
<h2 className="text-xl font-semibold mb-4 text-gray-700">{t.deviationsFromPlan}</h2>
|
||||
{deviations.map((dev, index) => (
|
||||
<div key={index} className="flex items-center space-x-2 mb-2 p-2 bg-white rounded flex-wrap">
|
||||
<div key={index} className="flex items-center gap-3 mb-2 p-2 bg-white rounded flex-wrap">
|
||||
<select
|
||||
value={dev.dayOffset || 0}
|
||||
onChange={e => onDeviationChange(index, 'dayOffset', parseInt(e.target.value, 10))}
|
||||
@@ -40,11 +40,11 @@ const DeviationList = ({
|
||||
</div>
|
||||
<button
|
||||
onClick={() => onRemoveDeviation(index)}
|
||||
className="text-red-500 hover:text-red-700 font-bold text-lg"
|
||||
className="text-red-500 hover:text-red-700 font-bold text-lg px-1"
|
||||
>
|
||||
×
|
||||
</button>
|
||||
<div className="flex items-center mt-1" title={t.additionalTooltip}>
|
||||
<div className="flex items-center" title={t.additionalTooltip}>
|
||||
<input
|
||||
type="checkbox"
|
||||
id={`add_dose_${index}`}
|
||||
@@ -52,7 +52,7 @@ const DeviationList = ({
|
||||
onChange={e => onDeviationChange(index, 'isAdditional', e.target.checked)}
|
||||
className="h-4 w-4 rounded border-gray-300 text-sky-600 focus:ring-sky-500"
|
||||
/>
|
||||
<label htmlFor={`add_dose_${index}`} className="ml-2 text-xs text-gray-600">
|
||||
<label htmlFor={`add_dose_${index}`} className="ml-2 text-xs text-gray-600 whitespace-nowrap">
|
||||
{t.additional}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -1,13 +1,42 @@
|
||||
import React from 'react';
|
||||
|
||||
const NumericInput = ({ value, onChange, increment, min = -Infinity, max = Infinity, placeholder, unit }) => {
|
||||
const NumericInput = ({
|
||||
value,
|
||||
onChange,
|
||||
increment,
|
||||
min = -Infinity,
|
||||
max = Infinity,
|
||||
placeholder,
|
||||
unit,
|
||||
align = 'right' // 'left', 'center', 'right'
|
||||
}) => {
|
||||
// Determine decimal places based on increment
|
||||
const getDecimalPlaces = () => {
|
||||
const inc = String(increment || '1');
|
||||
const decimalIndex = inc.indexOf('.');
|
||||
if (decimalIndex === -1) return 0;
|
||||
return inc.length - decimalIndex - 1;
|
||||
};
|
||||
|
||||
const decimalPlaces = getDecimalPlaces();
|
||||
|
||||
// Format value for display
|
||||
const formatValue = (val) => {
|
||||
const num = Number(val);
|
||||
if (isNaN(num)) return val;
|
||||
return num.toFixed(decimalPlaces);
|
||||
};
|
||||
|
||||
const updateValue = (direction) => {
|
||||
const numIncrement = parseFloat(increment) || 1;
|
||||
let numValue = parseFloat(value) || 0;
|
||||
let numValue = Number(value);
|
||||
if (isNaN(numValue)) {
|
||||
numValue = min !== -Infinity ? min : 0;
|
||||
}
|
||||
numValue += direction * numIncrement;
|
||||
numValue = Math.max(min, numValue);
|
||||
numValue = Math.min(max, numValue);
|
||||
const finalValue = String(Math.round(numValue * 100) / 100);
|
||||
const finalValue = formatValue(numValue);
|
||||
onChange(finalValue);
|
||||
};
|
||||
|
||||
@@ -20,16 +49,38 @@ const NumericInput = ({ value, onChange, increment, min = -Infinity, max = Infin
|
||||
|
||||
const handleChange = (e) => {
|
||||
const val = e.target.value;
|
||||
// Only allow valid numbers or empty string
|
||||
if (val === '' || /^-?\d*\.?\d*$/.test(val)) {
|
||||
// Prevent object values
|
||||
if (typeof val === 'object') return;
|
||||
onChange(val);
|
||||
}
|
||||
};
|
||||
|
||||
const handleBlur = (e) => {
|
||||
const val = e.target.value;
|
||||
if (val !== '' && !isNaN(Number(val))) {
|
||||
// Format the value when user finishes editing
|
||||
onChange(formatValue(val));
|
||||
}
|
||||
};
|
||||
|
||||
// Get alignment class
|
||||
const getAlignmentClass = () => {
|
||||
switch (align) {
|
||||
case 'left': return 'text-left';
|
||||
case 'center': return 'text-center';
|
||||
case 'right': return 'text-right';
|
||||
default: return 'text-right';
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex items-center w-full">
|
||||
<button
|
||||
onClick={() => updateValue(-1)}
|
||||
className="px-2 py-1 border rounded-l-md bg-gray-100 hover:bg-gray-200 text-lg font-bold"
|
||||
tabIndex={-1}
|
||||
>
|
||||
-
|
||||
</button>
|
||||
@@ -38,12 +89,15 @@ const NumericInput = ({ value, onChange, increment, min = -Infinity, max = Infin
|
||||
value={value}
|
||||
onChange={handleChange}
|
||||
onKeyDown={handleKeyDown}
|
||||
onBlur={handleBlur}
|
||||
placeholder={placeholder}
|
||||
className="p-2 border-t border-b w-full text-sm text-center"
|
||||
style={{ width: '4em', minWidth: '4em', maxWidth: '8em' }}
|
||||
className={`p-2 border-t border-b text-sm ${getAlignmentClass()}`}
|
||||
/>
|
||||
<button
|
||||
onClick={() => updateValue(1)}
|
||||
className="px-2 py-1 border rounded-r-md bg-gray-100 hover:bg-gray-200 text-lg font-bold"
|
||||
tabIndex={-1}
|
||||
>
|
||||
+
|
||||
</button>
|
||||
|
||||
@@ -55,7 +55,7 @@ const Settings = ({
|
||||
</div>
|
||||
|
||||
<label className="block font-medium text-gray-600 pt-2">{t.yAxisRange}</label>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div className="flex items-center space-x-3 mt-1">
|
||||
<div className="w-32">
|
||||
<NumericInput
|
||||
value={yAxisMin}
|
||||
@@ -66,7 +66,7 @@ const Settings = ({
|
||||
unit="ng/ml"
|
||||
/>
|
||||
</div>
|
||||
<span className="text-gray-500">-</span>
|
||||
<span className="text-gray-500 px-2">-</span>
|
||||
<div className="w-32">
|
||||
<NumericInput
|
||||
value={yAxisMax}
|
||||
@@ -80,7 +80,7 @@ const Settings = ({
|
||||
</div>
|
||||
|
||||
<label className="block font-medium text-gray-600">{t.therapeuticRange}</label>
|
||||
<div className="flex items-center space-x-2 mt-1">
|
||||
<div className="flex items-center space-x-3 mt-1">
|
||||
<div className="w-32">
|
||||
<NumericInput
|
||||
value={therapeuticRange.min}
|
||||
@@ -91,7 +91,7 @@ const Settings = ({
|
||||
unit="ng/ml"
|
||||
/>
|
||||
</div>
|
||||
<span className="text-gray-500">-</span>
|
||||
<span className="text-gray-500 px-2">-</span>
|
||||
<div className="w-32">
|
||||
<NumericInput
|
||||
value={therapeuticRange.max}
|
||||
|
||||
Reference in New Issue
Block a user