Update new unified dose management, style/other improvements
This commit is contained in:
@@ -10,7 +10,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { LOCAL_STORAGE_KEY, getDefaultState, type AppState } from '../constants/defaults';
|
||||
import { LOCAL_STORAGE_KEY, getDefaultState, type AppState, type DayGroup, type DayDose } from '../constants/defaults';
|
||||
|
||||
export const useAppState = () => {
|
||||
const [appState, setAppState] = React.useState<AppState>(getDefaultState);
|
||||
@@ -26,6 +26,7 @@ export const useAppState = () => {
|
||||
...defaults,
|
||||
...parsedState,
|
||||
pkParams: {...defaults.pkParams, ...parsedState.pkParams},
|
||||
days: parsedState.days || defaults.days,
|
||||
uiSettings: {...defaults.uiSettings, ...parsedState.uiSettings},
|
||||
});
|
||||
}
|
||||
@@ -40,7 +41,7 @@ export const useAppState = () => {
|
||||
try {
|
||||
const stateToSave = {
|
||||
pkParams: appState.pkParams,
|
||||
doses: appState.doses,
|
||||
days: appState.days,
|
||||
steadyStateConfig: appState.steadyStateConfig,
|
||||
therapeuticRange: appState.therapeuticRange,
|
||||
doseIncrement: appState.doseIncrement,
|
||||
@@ -72,15 +73,119 @@ export const useAppState = () => {
|
||||
key: K,
|
||||
value: AppState['uiSettings'][K]
|
||||
) => {
|
||||
const newUiSettings = { ...appState.uiSettings, [key]: value };
|
||||
if (key === 'simulationDays') {
|
||||
const simDaysNum = parseInt(value as string, 10) || 1;
|
||||
const dispDaysNum = parseInt(newUiSettings.displayedDays, 10) || 1;
|
||||
if (dispDaysNum > simDaysNum) {
|
||||
newUiSettings.displayedDays = String(simDaysNum);
|
||||
setAppState(prev => {
|
||||
const newUiSettings = { ...prev.uiSettings, [key]: value };
|
||||
|
||||
// Auto-adjust displayedDays if simulationDays is reduced
|
||||
if (key === 'simulationDays') {
|
||||
const simDays = parseInt(value as string, 10) || 3;
|
||||
const dispDays = parseInt(prev.uiSettings.displayedDays, 10) || 2;
|
||||
if (dispDays > simDays) {
|
||||
newUiSettings.displayedDays = String(simDays);
|
||||
}
|
||||
}
|
||||
}
|
||||
setAppState(prev => ({ ...prev, uiSettings: newUiSettings }));
|
||||
|
||||
return { ...prev, uiSettings: newUiSettings };
|
||||
});
|
||||
};
|
||||
|
||||
// Day management functions
|
||||
const addDay = (cloneFromDayId?: string) => {
|
||||
const maxDays = 3; // Template + 2 deviation days
|
||||
if (appState.days.length >= maxDays) return;
|
||||
|
||||
const sourceDay = cloneFromDayId
|
||||
? appState.days.find(d => d.id === cloneFromDayId)
|
||||
: undefined;
|
||||
|
||||
const newDay: DayGroup = sourceDay
|
||||
? {
|
||||
id: `day-${Date.now()}`,
|
||||
isTemplate: false,
|
||||
doses: sourceDay.doses.map(d => ({
|
||||
id: `dose-${Date.now()}-${Math.random()}`,
|
||||
time: d.time,
|
||||
ldx: d.ldx
|
||||
}))
|
||||
}
|
||||
: {
|
||||
id: `day-${Date.now()}`,
|
||||
isTemplate: false,
|
||||
doses: [{ id: `dose-${Date.now()}`, time: '12:00', ldx: '30' }]
|
||||
};
|
||||
|
||||
setAppState(prev => ({ ...prev, days: [...prev.days, newDay] }));
|
||||
};
|
||||
|
||||
const removeDay = (dayId: string) => {
|
||||
setAppState(prev => {
|
||||
const dayToRemove = prev.days.find(d => d.id === dayId);
|
||||
// Never delete template day
|
||||
if (dayToRemove?.isTemplate) {
|
||||
console.warn('Cannot delete template day');
|
||||
return prev;
|
||||
}
|
||||
// Never delete if it would leave us with no days
|
||||
if (prev.days.length <= 1) {
|
||||
console.warn('Cannot delete last day');
|
||||
return prev;
|
||||
}
|
||||
return { ...prev, days: prev.days.filter(d => d.id !== dayId) };
|
||||
});
|
||||
};
|
||||
|
||||
const updateDay = (dayId: string, updatedDay: DayGroup) => {
|
||||
setAppState(prev => ({
|
||||
...prev,
|
||||
days: prev.days.map(day => day.id === dayId ? updatedDay : day)
|
||||
}));
|
||||
};
|
||||
|
||||
const addDoseToDay = (dayId: string, newDose?: Partial<DayDose>) => {
|
||||
setAppState(prev => ({
|
||||
...prev,
|
||||
days: prev.days.map(day => {
|
||||
if (day.id !== dayId) return day;
|
||||
if (day.doses.length >= 5) return day; // Max 5 doses per day
|
||||
|
||||
const dose: DayDose = {
|
||||
id: `dose-${Date.now()}-${Math.random()}`,
|
||||
time: newDose?.time || '12:00',
|
||||
ldx: newDose?.ldx || '0',
|
||||
damph: newDose?.damph || '0',
|
||||
};
|
||||
|
||||
return { ...day, doses: [...day.doses, dose] };
|
||||
})
|
||||
}));
|
||||
};
|
||||
|
||||
const removeDoseFromDay = (dayId: string, doseId: string) => {
|
||||
setAppState(prev => ({
|
||||
...prev,
|
||||
days: prev.days.map(day => {
|
||||
if (day.id !== dayId) return day;
|
||||
// Don't allow removing last dose from template day
|
||||
if (day.isTemplate && day.doses.length <= 1) return day;
|
||||
|
||||
return { ...day, doses: day.doses.filter(dose => dose.id !== doseId) };
|
||||
})
|
||||
}));
|
||||
};
|
||||
|
||||
const updateDoseInDay = (dayId: string, doseId: string, field: keyof DayDose, value: string) => {
|
||||
setAppState(prev => ({
|
||||
...prev,
|
||||
days: prev.days.map(day => {
|
||||
if (day.id !== dayId) return day;
|
||||
return {
|
||||
...day,
|
||||
doses: day.doses.map(dose =>
|
||||
dose.id === doseId ? { ...dose, [field]: value } : dose
|
||||
)
|
||||
};
|
||||
})
|
||||
}));
|
||||
};
|
||||
|
||||
const handleReset = () => {
|
||||
@@ -96,6 +201,12 @@ export const useAppState = () => {
|
||||
updateState,
|
||||
updateNestedState,
|
||||
updateUiSetting,
|
||||
addDay,
|
||||
removeDay,
|
||||
updateDay,
|
||||
addDoseToDay,
|
||||
removeDoseFromDay,
|
||||
updateDoseInDay,
|
||||
handleReset
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user