Update settings add min<=max validation to ranges, minor text changes
This commit is contained in:
@@ -134,6 +134,10 @@ const Settings = ({
|
||||
// Track which tooltip is currently open (for mobile touch interaction)
|
||||
const [openTooltipId, setOpenTooltipId] = React.useState<string | null>(null);
|
||||
|
||||
// Validation state for range inputs
|
||||
const [therapeuticRangeError, setTherapeuticRangeError] = React.useState<string>('');
|
||||
const [yAxisRangeError, setYAxisRangeError] = React.useState<string>('');
|
||||
|
||||
// Track window width for responsive tooltip positioning
|
||||
const [isNarrowScreen, setIsNarrowScreen] = React.useState(
|
||||
typeof window !== 'undefined' ? window.innerWidth < 640 : false
|
||||
@@ -226,6 +230,27 @@ const Settings = ({
|
||||
// Create defaults object for translation interpolation
|
||||
const defaultsForT = getDefaultsForTranslation(pkParams, therapeuticRange, uiSettings);
|
||||
|
||||
// Validate range inputs
|
||||
React.useEffect(() => {
|
||||
// Therapeutic range validation (blocking error)
|
||||
const minTherapeutic = parseFloat(therapeuticRange.min);
|
||||
const maxTherapeutic = parseFloat(therapeuticRange.max);
|
||||
if (!isNaN(minTherapeutic) && !isNaN(maxTherapeutic) && minTherapeutic >= maxTherapeutic) {
|
||||
setTherapeuticRangeError(t('errorTherapeuticRangeInvalid'));
|
||||
} else {
|
||||
setTherapeuticRangeError('');
|
||||
}
|
||||
|
||||
// Y-axis range validation (non-blocking warning)
|
||||
const minYAxis = parseFloat(yAxisMin);
|
||||
const maxYAxis = parseFloat(yAxisMax);
|
||||
if (!isNaN(minYAxis) && !isNaN(maxYAxis) && minYAxis >= maxYAxis) {
|
||||
setYAxisRangeError(t('errorYAxisRangeInvalid'));
|
||||
} else {
|
||||
setYAxisRangeError('');
|
||||
}
|
||||
}, [therapeuticRange.min, therapeuticRange.max, yAxisMin, yAxisMax, t]);
|
||||
|
||||
// Helper to update nested advanced settings
|
||||
const updateAdvanced = (category: string, key: string, value: any) => {
|
||||
onUpdatePkParams('advanced', {
|
||||
@@ -380,7 +405,8 @@ const Settings = ({
|
||||
min={0}
|
||||
placeholder={t('min')}
|
||||
required={true}
|
||||
errorMessage={t('errorTherapeuticRangeMinRequired') || 'Minimum therapeutic range is required'}
|
||||
error={!!therapeuticRangeError || !therapeuticRange.min}
|
||||
errorMessage={therapeuticRangeError || t('errorTherapeuticRangeMinRequired') || 'Minimum therapeutic range is required'}
|
||||
/>
|
||||
<span className="text-muted-foreground">-</span>
|
||||
<FormNumericInput
|
||||
@@ -391,7 +417,8 @@ const Settings = ({
|
||||
placeholder={t('max')}
|
||||
unit="ng/ml"
|
||||
required={true}
|
||||
errorMessage={t('errorTherapeuticRangeMaxRequired') || 'Maximum therapeutic range is required'}
|
||||
error={!!therapeuticRangeError || !therapeuticRange.max}
|
||||
errorMessage={therapeuticRangeError || t('errorTherapeuticRangeMaxRequired') || 'Maximum therapeutic range is required'}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -461,6 +488,8 @@ const Settings = ({
|
||||
placeholder={t('auto')}
|
||||
allowEmpty={true}
|
||||
clearButton={true}
|
||||
warning={!!yAxisRangeError}
|
||||
warningMessage={yAxisRangeError}
|
||||
/>
|
||||
<span className="text-muted-foreground">-</span>
|
||||
<FormNumericInput
|
||||
@@ -472,6 +501,8 @@ const Settings = ({
|
||||
unit="ng/ml"
|
||||
allowEmpty={true}
|
||||
clearButton={true}
|
||||
warning={!!yAxisRangeError}
|
||||
warningMessage={yAxisRangeError}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -159,7 +159,7 @@ export const getDefaultState = (): AppState => ({
|
||||
}
|
||||
],
|
||||
steadyStateConfig: { daysOnMedication: '7' }, // kept for backwards compatibility, now sourced from pkParams.advanced
|
||||
therapeuticRange: { min: '', max: '' }, // Empty by default - users should personalize based on their response
|
||||
therapeuticRange: { min: '10', max: '120' }, // min for adults and max for children for maximum range (users should personalize based on their response)
|
||||
doseIncrement: '2.5',
|
||||
uiSettings: {
|
||||
showDayTimeOnXAxis: '24h',
|
||||
@@ -168,7 +168,7 @@ export const getDefaultState = (): AppState => ({
|
||||
yAxisMin: '',
|
||||
yAxisMax: '',
|
||||
simulationDays: '5',
|
||||
displayedDays: '2',
|
||||
displayedDays: '1',
|
||||
showTherapeuticRange: false,
|
||||
steadyStateDaysEnabled: true,
|
||||
stickyChart: false,
|
||||
|
||||
@@ -108,7 +108,7 @@ export const de = {
|
||||
yAxisRangeAutoButton: "A",
|
||||
yAxisRangeAutoButtonTitle: "Bereich automatisch anhand des Datenbereichs bestimmen",
|
||||
auto: "Auto",
|
||||
therapeuticRange: "Therapeutischer Bereich",
|
||||
therapeuticRange: "Therapeutischer Bereich (d-Amphetamin)",
|
||||
therapeuticRangeTooltip: "Personalisierte Konzentrationsziele basierend auf DEINER individuellen Reaktion. Setze diese nachdem du beobachtet hast, welche Werte Symptomkontrolle vs. Nebenwirkungen bieten. Referenzbereiche (stark variabel): Erwachsene ~10-80 ng/mL, Kinder ~20-120 ng/mL (aufgrund geringeren Körpergewichts/Vd). Leer lassen wenn unsicher. Konsultiere deinen Arzt.",
|
||||
dAmphetamineParameters: "d-Amphetamin Parameter",
|
||||
halfLife: "Eliminations-Halbwertszeit",
|
||||
@@ -269,6 +269,8 @@ export const de = {
|
||||
errorConversionHalfLifeRequired: "⛔ Umwandlungs-Halbwertszeit ist erforderlich.",
|
||||
errorTherapeuticRangeMinRequired: "⛔ Minimaler therapeutischer Bereich ist erforderlich.",
|
||||
errorTherapeuticRangeMaxRequired: "⛔ Maximaler therapeutischer Bereich ist erforderlich.",
|
||||
errorTherapeuticRangeInvalid: "⛔ Maximum muss größer als Minimum sein.",
|
||||
errorYAxisRangeInvalid: "⚠️ Maximum muss größer als Minimum sein.",
|
||||
errorEliminationHalfLifeRequired: "⛔ Eliminations-Halbwertszeit ist erforderlich.",
|
||||
|
||||
// Field validation - Warnings
|
||||
|
||||
@@ -106,7 +106,7 @@ export const en = {
|
||||
yAxisRangeAutoButton: "A",
|
||||
yAxisRangeAutoButtonTitle: "Determine range automatically based on data range",
|
||||
auto: "Auto",
|
||||
therapeuticRange: "Therapeutic Range",
|
||||
therapeuticRange: "Therapeutic Range (d-Amphetamine)",
|
||||
therapeuticRangeTooltip: "Personalized concentration targets based on YOUR individual response. Set these after observing which levels provide symptom control vs. side effects. Reference ranges (highly variable): Adults ~10-80 ng/mL, Children ~20-120 ng/mL (due to lower body weight/Vd). Leave empty if unsure. Consult your physician.",
|
||||
dAmphetamineParameters: "d-Amphetamine Parameters",
|
||||
halfLife: "Elimination Half-life",
|
||||
@@ -268,6 +268,8 @@ export const en = {
|
||||
errorAbsorptionRateRequired: "⛔ Absorption rate is required.",
|
||||
errorTherapeuticRangeMinRequired: "⛔ Minimum therapeutic range is required.",
|
||||
errorTherapeuticRangeMaxRequired: "⛔ Maximum therapeutic range is required.",
|
||||
errorTherapeuticRangeInvalid: "⛔ Maximum must be greater than minimum.",
|
||||
errorYAxisRangeInvalid: "⚠️ Maximum must be greater than minimum.",
|
||||
errorEliminationHalfLifeRequired: "⛔ Elimination half-life is required.",
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user