Update migrated js to ts and shadcn
This commit is contained in:
@@ -1,15 +1,21 @@
|
||||
import { timeToMinutes } from './timeUtils.js';
|
||||
import { calculateSingleDoseConcentration } from './pharmacokinetics.js';
|
||||
import { timeToMinutes } from './timeUtils';
|
||||
import { calculateSingleDoseConcentration } from './pharmacokinetics';
|
||||
import type { Dose, Deviation, SteadyStateConfig, PkParams, ConcentrationPoint } from '../constants/defaults';
|
||||
|
||||
interface DoseWithTime extends Omit<Dose, 'time'> {
|
||||
time: number;
|
||||
isPlan?: boolean;
|
||||
}
|
||||
|
||||
export const calculateCombinedProfile = (
|
||||
doseSchedule,
|
||||
deviationList = [],
|
||||
correction = null,
|
||||
steadyStateConfig,
|
||||
simulationDays,
|
||||
pkParams
|
||||
) => {
|
||||
const dataPoints = [];
|
||||
doseSchedule: Dose[],
|
||||
deviationList: Deviation[] = [],
|
||||
correction: Deviation | null = null,
|
||||
steadyStateConfig: SteadyStateConfig,
|
||||
simulationDays: string,
|
||||
pkParams: PkParams
|
||||
): ConcentrationPoint[] => {
|
||||
const dataPoints: ConcentrationPoint[] = [];
|
||||
const timeStepHours = 0.25;
|
||||
const totalHours = (parseInt(simulationDays, 10) || 3) * 24;
|
||||
const daysToSimulate = Math.min(parseInt(steadyStateConfig.daysOnMedication, 10) || 0, 5);
|
||||
@@ -17,13 +23,21 @@ export const calculateCombinedProfile = (
|
||||
for (let t = 0; t <= totalHours; t += timeStepHours) {
|
||||
let totalLdx = 0;
|
||||
let totalDamph = 0;
|
||||
let allDoses = [];
|
||||
const allDoses: DoseWithTime[] = [];
|
||||
|
||||
const maxDayOffset = (parseInt(simulationDays, 10) || 3) - 1;
|
||||
|
||||
for (let day = -daysToSimulate; day <= maxDayOffset; day++) {
|
||||
const dayOffset = day * 24 * 60;
|
||||
doseSchedule.forEach(d => {
|
||||
// Skip doses with empty or invalid time values
|
||||
const timeStr = String(d.time || '').trim();
|
||||
const doseStr = String(d.dose || '').trim();
|
||||
const doseNum = parseFloat(doseStr);
|
||||
|
||||
if (!timeStr || timeStr === '' || !doseStr || doseStr === '' || doseNum === 0 || isNaN(doseNum)) {
|
||||
return;
|
||||
}
|
||||
allDoses.push({ ...d, time: timeToMinutes(d.time) + dayOffset, isPlan: true });
|
||||
});
|
||||
}
|
||||
@@ -34,6 +48,14 @@ export const calculateCombinedProfile = (
|
||||
}
|
||||
|
||||
currentDeviations.forEach(dev => {
|
||||
// Skip deviations with empty or invalid time values
|
||||
const timeStr = String(dev.time || '').trim();
|
||||
const doseStr = String(dev.dose || '').trim();
|
||||
const doseNum = parseFloat(doseStr);
|
||||
|
||||
if (!timeStr || timeStr === '' || !doseStr || doseStr === '' || doseNum === 0 || isNaN(doseNum)) {
|
||||
return;
|
||||
}
|
||||
const devTime = timeToMinutes(dev.time) + (dev.dayOffset || 0) * 24 * 60;
|
||||
if (!dev.isAdditional) {
|
||||
const closestDoseIndex = allDoses.reduce((closest, dose, index) => {
|
||||
@@ -1,7 +1,16 @@
|
||||
import { LDX_TO_DAMPH_CONVERSION_FACTOR } from '../constants/defaults.js';
|
||||
import { LDX_TO_DAMPH_CONVERSION_FACTOR, type PkParams } from '../constants/defaults';
|
||||
|
||||
interface ConcentrationResult {
|
||||
ldx: number;
|
||||
damph: number;
|
||||
}
|
||||
|
||||
// Pharmacokinetic calculations
|
||||
export const calculateSingleDoseConcentration = (dose, timeSinceDoseHours, pkParams) => {
|
||||
export const calculateSingleDoseConcentration = (
|
||||
dose: string,
|
||||
timeSinceDoseHours: number,
|
||||
pkParams: PkParams
|
||||
): ConcentrationResult => {
|
||||
const numDose = parseFloat(dose) || 0;
|
||||
if (timeSinceDoseHours < 0 || numDose <= 0) return { ldx: 0, damph: 0 };
|
||||
|
||||
@@ -1,14 +1,24 @@
|
||||
import { timeToMinutes } from './timeUtils.js';
|
||||
import { calculateCombinedProfile } from './calculations.js';
|
||||
import { timeToMinutes } from './timeUtils';
|
||||
import { calculateCombinedProfile } from './calculations';
|
||||
import type { Dose, Deviation, SteadyStateConfig, PkParams } from '../constants/defaults';
|
||||
|
||||
interface SuggestionResult {
|
||||
text?: string;
|
||||
time?: string;
|
||||
dose?: string;
|
||||
isAdditional?: boolean;
|
||||
originalDose?: string;
|
||||
dayOffset?: number;
|
||||
}
|
||||
|
||||
export const generateSuggestion = (
|
||||
doses,
|
||||
deviations,
|
||||
doseIncrement,
|
||||
simulationDays,
|
||||
steadyStateConfig,
|
||||
pkParams
|
||||
) => {
|
||||
doses: Dose[],
|
||||
deviations: Deviation[],
|
||||
doseIncrement: string,
|
||||
simulationDays: string,
|
||||
steadyStateConfig: SteadyStateConfig,
|
||||
pkParams: PkParams
|
||||
): SuggestionResult | null => {
|
||||
if (deviations.length === 0) {
|
||||
return null;
|
||||
}
|
||||
@@ -18,12 +28,23 @@ export const generateSuggestion = (
|
||||
(timeToMinutes(b.time) + (b.dayOffset || 0) * 1440)
|
||||
).pop();
|
||||
|
||||
if (!lastDeviation) return null;
|
||||
|
||||
const deviationTimeTotalMinutes = timeToMinutes(lastDeviation.time) + (lastDeviation.dayOffset || 0) * 1440;
|
||||
|
||||
let nextDose = null;
|
||||
type DoseWithOffset = Dose & { dayOffset: number };
|
||||
let nextDose: DoseWithOffset | null = null;
|
||||
let minDiff = Infinity;
|
||||
|
||||
doses.forEach(d => {
|
||||
// Skip doses with empty or invalid time/dose values
|
||||
const timeStr = String(d.time || '').trim();
|
||||
const doseStr = String(d.dose || '').trim();
|
||||
const doseNum = parseFloat(doseStr);
|
||||
|
||||
if (!timeStr || timeStr === '' || !doseStr || doseStr === '' || doseNum === 0 || isNaN(doseNum)) {
|
||||
return;
|
||||
}
|
||||
const doseTimeInMinutes = timeToMinutes(d.time);
|
||||
for (let i = 0; i < (parseInt(simulationDays, 10) || 1); i++) {
|
||||
const absoluteTime = doseTimeInMinutes + i * 1440;
|
||||
@@ -39,11 +60,14 @@ export const generateSuggestion = (
|
||||
return { text: "Keine passende nächste Dosis für Korrektur gefunden." };
|
||||
}
|
||||
|
||||
// Type assertion after null check
|
||||
const confirmedNextDose: DoseWithOffset = nextDose;
|
||||
|
||||
const numDoseIncrement = parseFloat(doseIncrement) || 1;
|
||||
const idealProfile = calculateCombinedProfile(doses, [], null, steadyStateConfig, simulationDays, pkParams);
|
||||
const deviatedProfile = calculateCombinedProfile(doses, deviations, null, steadyStateConfig, simulationDays, pkParams);
|
||||
|
||||
const nextDoseTimeHours = (timeToMinutes(nextDose.time) + (nextDose.dayOffset || 0) * 1440) / 60;
|
||||
const nextDoseTimeHours = (timeToMinutes(confirmedNextDose.time) + (confirmedNextDose.dayOffset || 0) * 1440) / 60;
|
||||
|
||||
const idealConcentration = idealProfile.find(p => Math.abs(p.timeHours - nextDoseTimeHours) < 0.1)?.damph || 0;
|
||||
const deviatedConcentration = deviatedProfile.find(p => Math.abs(p.timeHours - nextDoseTimeHours) < 0.1)?.damph || 0;
|
||||
@@ -56,14 +80,14 @@ export const generateSuggestion = (
|
||||
const doseAdjustmentFactor = 0.5;
|
||||
let doseChange = concentrationDifference / doseAdjustmentFactor;
|
||||
doseChange = Math.round(doseChange / numDoseIncrement) * numDoseIncrement;
|
||||
let suggestedDoseValue = (parseFloat(nextDose.dose) || 0) + doseChange;
|
||||
let suggestedDoseValue = (parseFloat(confirmedNextDose.dose) || 0) + doseChange;
|
||||
suggestedDoseValue = Math.max(0, Math.min(70, suggestedDoseValue));
|
||||
|
||||
return {
|
||||
time: nextDose.time,
|
||||
time: confirmedNextDose.time,
|
||||
dose: String(suggestedDoseValue),
|
||||
isAdditional: false,
|
||||
originalDose: nextDose.dose,
|
||||
dayOffset: nextDose.dayOffset
|
||||
originalDose: confirmedNextDose.dose,
|
||||
dayOffset: confirmedNextDose.dayOffset
|
||||
};
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
// --- Helper Functions ---
|
||||
export const timeToMinutes = (timeStr) => {
|
||||
// Time utility functions
|
||||
export const timeToMinutes = (timeStr: string): number => {
|
||||
if (!timeStr || !timeStr.includes(':')) return 0;
|
||||
const [hours, minutes] = timeStr.split(':').map(Number);
|
||||
return hours * 60 + minutes;
|
||||
Reference in New Issue
Block a user