diff --git a/src/components/DeviationList.js b/src/components/DeviationList.js index 47e7380..4afec3e 100644 --- a/src/components/DeviationList.js +++ b/src/components/DeviationList.js @@ -28,7 +28,7 @@ const DeviationList = ({ onDeviationChange(index, 'time', newTime)} - errorMessage={t.timeRequired} + errorMessage={t.errorTimeRequired} />
{ onUpdateDoses(doses.map((d, i) => i === index ? {...d, time: newTime} : d))} - errorMessage={t.timeRequired} + errorMessage={t.errorTimeRequired} />
{ const [hasError, setHasError] = React.useState(false); @@ -166,51 +168,51 @@ const NumericInput = ({ onMouseLeave={handleMouseLeave} >
- - - - {showClearButton && ( +
+ + + + {showClearButton && ( - )} - {hasError && ( -
- )} + + )} + )} +
{unit && {unit}}
{hasError && showErrorTooltip && (
{ const { showDayTimeOnXAxis, yAxisMin, yAxisMax, simulationDays, displayedDays } = uiSettings; + // https://www.svgrepo.com/svg/509013/actual-size + const clearButtonSVG = ( ); return (
@@ -38,8 +40,9 @@ const Settings = ({ increment={'1'} min={2} max={7} + placeholder="#" unit={t.days} - errorMessage={t.fieldRequired} + errorMessage={t.errorNumberRequired} />
@@ -51,8 +54,9 @@ const Settings = ({ increment={'1'} min={1} max={parseInt(simulationDays, 10) || 1} + placeholder="#" unit={t.days} - errorMessage={t.fieldRequired} + errorMessage={t.errorNumberRequired} />
@@ -68,6 +72,8 @@ const Settings = ({ placeholder={t.auto} allowEmpty={true} clearButton={true} + clearButtonText={clearButtonSVG || t.yAxisRangeAutoButton} + clearButtonTitle={t.yAxisRangeAutoButtonTitle} />
- @@ -81,6 +87,8 @@ const Settings = ({ unit="ng/ml" allowEmpty={true} clearButton={true} + clearButtonText={clearButtonSVG || t.yAxisRangeAutoButton} + clearButtonTitle={t.yAxisRangeAutoButtonTitle} />
@@ -96,7 +104,7 @@ const Settings = ({ increment={'0.5'} min={0} placeholder={t.min} - errorMessage={t.fieldRequired} + errorMessage={t.errorNumberRequired} /> - @@ -108,7 +116,7 @@ const Settings = ({ min={0} placeholder={t.max} unit="ng/ml" - errorMessage={t.fieldRequired} + errorMessage={t.errorNumberRequired} /> @@ -122,8 +130,9 @@ const Settings = ({ onChange={val => onUpdatePkParams('damph', { halfLife: val })} increment={'0.5'} min={0.1} + placeholder="#.#" unit="h" - errorMessage={t.fieldRequired} + errorMessage={t.errorNumberRequired} /> @@ -135,8 +144,9 @@ const Settings = ({ onChange={val => onUpdatePkParams('ldx', { halfLife: val })} increment={'0.1'} min={0.1} + placeholder="#.#" unit="h" - errorMessage={t.fieldRequired} + errorMessage={t.errorNumberRequired} />
@@ -146,8 +156,9 @@ const Settings = ({ onChange={val => onUpdatePkParams('ldx', { absorptionRate: val })} increment={'0.1'} min={0.1} + placeholder="#.#" unit={t.faster} - errorMessage={t.fieldRequired} + errorMessage={t.errorNumberRequired} />
diff --git a/src/components/TimeInput.js b/src/components/TimeInput.js index 2aa3852..431f1ca 100644 --- a/src/components/TimeInput.js +++ b/src/components/TimeInput.js @@ -97,6 +97,25 @@ const TimeInput = ({ value, onChange, errorMessage = 'Time is required' }) => { setShowErrorTooltip(false); }; + const [tooltipPosition, setTooltipPosition] = React.useState({ top: true, left: true }); + + React.useEffect(() => { + if (showErrorTooltip && containerRef.current) { + const rect = containerRef.current.getBoundingClientRect(); + const tooltipWidth = 300; // Approximate width + const tooltipHeight = 60; // Approximate height + + const spaceRight = window.innerWidth - rect.right; + const spaceBottom = window.innerHeight - rect.bottom; + + setTooltipPosition({ + top: spaceBottom < tooltipHeight + 10, + left: spaceRight < tooltipWidth + }); + } + }, [showErrorTooltip]); + + return (
{ onMouseLeave={handleMouseLeave} >
-
+
{ onBlur={handleBlur} onFocus={handleFocus} placeholder="HH:MM" - className={`p-2 border rounded-md w-24 text-sm text-center ${hasError ? 'bg-red-50 border-transparent' : ''}`} + className={`p-2 border rounded-md w-24 text-sm text-center ${hasError ? 'border-transparent' : ''}`} />
)} {hasError && showErrorTooltip && ( -
+
- {errorMessage} + {errorMessage}
)}
diff --git a/src/constants/defaults.js b/src/constants/defaults.js index 58bc430..2a2da77 100644 --- a/src/constants/defaults.js +++ b/src/constants/defaults.js @@ -21,8 +21,8 @@ export const getDefaultState = () => ({ uiSettings: { showDayTimeOnXAxis: true, chartView: 'damph', - yAxisMin: '', - yAxisMax: '', + yAxisMin: '0', + yAxisMax: '16', simulationDays: '3', displayedDays: '2', } diff --git a/src/locales/de.js b/src/locales/de.js index 8b18960..323a754 100644 --- a/src/locales/de.js +++ b/src/locales/de.js @@ -51,6 +51,8 @@ export const de = { days: "Tage", displayedDays: "Angezeigte Tage", yAxisRange: "Y-Achsen-Bereich", + yAxisRangeAutoButton: "A", + yAxisRangeAutoButtonTitle: "Bereich automatisch anhand des Datenbereichs bestimmen", auto: "Auto", therapeuticRange: "Therapeutischer Bereich", dAmphetamineParameters: "d-Amphetamin Parameter", @@ -74,8 +76,8 @@ export const de = { disclaimer: "Dieses Tool dient ausschließlich zu Illustrations- und Informationszwecken. Es ist kein medizinisches Gerät und ersetzt nicht die Beratung durch einen Arzt oder Apotheker. Alle Berechnungen sind Simulationen, die auf allgemeinen pharmakokinetischen Modellen basieren und von individuellen Faktoren erheblich abweichen können. Bitte konsultiere deinen behandelnden Arzt, bevor du Anpassungen an deiner Medikation vornimmst.", // Field validation - fieldRequired: "Dieses Feld ist erforderlich", - timeRequired: "Zeitangabe ist erforderlich" + errorNumberRequired: "Bitte gib eine gültige Zahl ein.", + errorTimeRequired: "Bitte gib eine gültige Zeitangabe ein." }; export default de; diff --git a/src/locales/en.js b/src/locales/en.js index 952f317..1b9bc21 100644 --- a/src/locales/en.js +++ b/src/locales/en.js @@ -51,6 +51,8 @@ export const en = { days: "Days", displayedDays: "Displayed Days", yAxisRange: "Y-Axis Range", + yAxisRangeAutoButton: "A", + yAxisRangeAutoButtonTitle: "Determine range automatically based on data range", auto: "Auto", therapeuticRange: "Therapeutic Range", dAmphetamineParameters: "d-Amphetamine Parameters", @@ -74,8 +76,8 @@ export const en = { disclaimer: "This tool is for illustration and information purposes only. It is not a medical device and does not replace consultation with a doctor or pharmacist. All calculations are simulations based on general pharmacokinetic models and may differ significantly from individual factors. Please consult your treating physician before making adjustments to your medication.", // Field validation - fieldRequired: "This field is required", - timeRequired: "Time is required" + errorNumberRequired: "Please enter a valid number.", + errorTimeRequired: "Please enter a valid time." }; export default en;