SEPSIS_ICU_MIMIC / frontend /src /lib /formConfig.ts
Expanic
Update code
1eb43b0
Raw
History Blame Contribute Delete
15.9 kB
// Form configuration for all sepsis prediction input fields
// Organized by category with metadata for dynamic form generation
export interface ValidationRange {
normal: { min: number; max: number }; // Normal range
warning: { min: number; max: number }; // Warning range (show yellow)
critical: { min: number; max: number }; // Critical range (show red)
}
export interface FieldConfig {
name: string;
label: string;
type: 'number' | 'select' | 'text';
unit?: string;
hasMinMax?: boolean; // If true, generates _min and _max fields IN PAYLOAD, but shows single input
options?: { value: string; label: string }[];
required?: boolean;
placeholder?: string;
step?: string;
validation?: ValidationRange;
}
export interface CategoryConfig {
id: string;
label: string;
icon: string; // lucide icon name
description: string;
fields: FieldConfig[];
}
export const formCategories: CategoryConfig[] = [
{
id: 'demographics',
label: 'Patient Demographics',
icon: 'User',
description: 'Basic patient information and identifiers',
fields: [
{
name: 'age', label: 'Age', type: 'number', unit: 'years', required: true, placeholder: '65',
validation: { normal: { min: 18, max: 100 }, warning: { min: 0, max: 120 }, critical: { min: 0, max: 150 } }
},
{
name: 'f0_', label: 'Gender', type: 'select', required: true, options: [
{ value: 'M', label: 'Male' },
{ value: 'F', label: 'Female' }
]
},
{
name: 'height', label: 'Height', type: 'number', unit: 'cm', placeholder: '170',
validation: { normal: { min: 100, max: 220 }, warning: { min: 50, max: 250 }, critical: { min: 30, max: 300 } }
},
]
},
{
id: 'vitals',
label: 'Vital Signs',
icon: 'Activity',
description: 'Core vital sign measurements',
fields: [
{
name: 'heart_rate', label: 'Heart Rate', type: 'number', unit: 'bpm', hasMinMax: true,
validation: { normal: { min: 60, max: 100 }, warning: { min: 40, max: 150 }, critical: { min: 20, max: 250 } }
},
{
name: 'sbp', label: 'Systolic BP', type: 'number', unit: 'mmHg', hasMinMax: true,
validation: { normal: { min: 90, max: 140 }, warning: { min: 70, max: 180 }, critical: { min: 40, max: 260 } }
},
{
name: 'dbp', label: 'Diastolic BP', type: 'number', unit: 'mmHg', hasMinMax: true,
validation: { normal: { min: 60, max: 90 }, warning: { min: 40, max: 120 }, critical: { min: 20, max: 180 } }
},
{
name: 'mbp', label: 'Mean Arterial Pressure', type: 'number', unit: 'mmHg', hasMinMax: true,
validation: { normal: { min: 70, max: 100 }, warning: { min: 50, max: 130 }, critical: { min: 30, max: 180 } }
},
{
name: 'resp_rate', label: 'Respiratory Rate', type: 'number', unit: '/min', hasMinMax: true,
validation: { normal: { min: 12, max: 20 }, warning: { min: 8, max: 35 }, critical: { min: 4, max: 60 } }
},
{
name: 'temperature', label: 'Temperature', type: 'number', unit: '°C', hasMinMax: true, step: '0.1',
validation: { normal: { min: 36, max: 37.5 }, warning: { min: 35, max: 40 }, critical: { min: 30, max: 45 } }
},
{
name: 'spo2', label: 'SpO2', type: 'number', unit: '%', hasMinMax: true,
validation: { normal: { min: 95, max: 100 }, warning: { min: 88, max: 100 }, critical: { min: 50, max: 100 } }
},
{
name: 'glucose', label: 'Glucose', type: 'number', unit: 'mg/dL', hasMinMax: true,
validation: { normal: { min: 70, max: 140 }, warning: { min: 40, max: 300 }, critical: { min: 10, max: 600 } }
},
]
},
{
id: 'labs',
label: 'Laboratory Results',
icon: 'Beaker',
description: 'Complete blood count and chemistry panel',
fields: [
{
name: 'wbc', label: 'WBC', type: 'number', unit: 'K/µL', hasMinMax: true,
validation: { normal: { min: 4, max: 11 }, warning: { min: 1, max: 25 }, critical: { min: 0, max: 100 } }
},
{
name: 'platelet', label: 'Platelets', type: 'number', unit: 'K/µL', hasMinMax: true,
validation: { normal: { min: 150, max: 400 }, warning: { min: 50, max: 600 }, critical: { min: 0, max: 1000 } }
},
{
name: 'hemoglobin', label: 'Hemoglobin', type: 'number', unit: 'g/dL', hasMinMax: true,
validation: { normal: { min: 12, max: 17 }, warning: { min: 7, max: 20 }, critical: { min: 3, max: 25 } }
},
{ name: 'neutrophils_abs', label: 'Neutrophils (Abs)', type: 'number', unit: 'K/µL', hasMinMax: true },
{ name: 'bands', label: 'Bands', type: 'number', unit: '%', hasMinMax: true },
{ name: 'immature_granulocytes', label: 'Immature Granulocytes', type: 'number', unit: '%', hasMinMax: true },
{ name: 'lymphocytes_abs', label: 'Lymphocytes (Abs)', type: 'number', unit: 'K/µL', hasMinMax: true },
{ name: 'fibrinogen', label: 'Fibrinogen', type: 'number', unit: 'mg/dL', hasMinMax: true },
{
name: 'inr', label: 'INR', type: 'number', hasMinMax: true, step: '0.1',
validation: { normal: { min: 0.8, max: 1.2 }, warning: { min: 0.5, max: 5 }, critical: { min: 0, max: 10 } }
},
{ name: 'pt', label: 'PT', type: 'number', unit: 'sec', hasMinMax: true },
{ name: 'antibiotic_count', label: 'Antibiotic Count', type: 'number', placeholder: '0' },
]
},
{
id: 'bloodgas',
label: 'Blood Gas Analysis',
icon: 'Wind',
description: 'Arterial blood gas and oxygenation parameters',
fields: [
{ name: 'so2', label: 'SaO2', type: 'number', unit: '%', hasMinMax: true },
{ name: 'po2', label: 'PaO2', type: 'number', unit: 'mmHg', hasMinMax: true },
{ name: 'pco2', label: 'PaCO2', type: 'number', unit: 'mmHg', hasMinMax: true },
{ name: 'fio2', label: 'FiO2', type: 'number', unit: '%', hasMinMax: true },
{ name: 'pfratio', label: 'P/F Ratio', type: 'number', hasMinMax: true },
{
name: 'ventilation_flag', label: 'On Ventilation', type: 'select', options: [
{ value: '0', label: 'No' },
{ value: '1', label: 'Yes' }
]
},
{
name: 'ph', label: 'pH', type: 'number', hasMinMax: true, step: '0.01',
validation: { normal: { min: 7.35, max: 7.45 }, warning: { min: 7.1, max: 7.6 }, critical: { min: 6.8, max: 7.8 } }
},
{ name: 'baseexcess', label: 'Base Excess', type: 'number', unit: 'mEq/L', hasMinMax: true },
{ name: 'bicarbonate', label: 'Bicarbonate', type: 'number', unit: 'mEq/L', hasMinMax: true },
{ name: 'totalco2', label: 'Total CO2', type: 'number', unit: 'mEq/L', hasMinMax: true },
{
name: 'lactate', label: 'Lactate', type: 'number', unit: 'mmol/L', hasMinMax: true,
validation: { normal: { min: 0.5, max: 2 }, warning: { min: 0, max: 4 }, critical: { min: 0, max: 20 } }
},
]
},
{
id: 'electrolytes',
label: 'Electrolytes',
icon: 'Droplets',
description: 'Serum electrolyte panel',
fields: [
{
name: 'sodium', label: 'Sodium', type: 'number', unit: 'mEq/L', hasMinMax: true,
validation: { normal: { min: 136, max: 145 }, warning: { min: 120, max: 160 }, critical: { min: 100, max: 180 } }
},
{
name: 'potassium', label: 'Potassium', type: 'number', unit: 'mEq/L', hasMinMax: true, step: '0.1',
validation: { normal: { min: 3.5, max: 5 }, warning: { min: 2.5, max: 6.5 }, critical: { min: 1.5, max: 8 } }
},
{ name: 'chloride', label: 'Chloride', type: 'number', unit: 'mEq/L', hasMinMax: true },
{ name: 'calcium', label: 'Calcium', type: 'number', unit: 'mg/dL', hasMinMax: true, step: '0.1' },
{ name: 'glucose_1', label: 'Glucose (Lab)', type: 'number', unit: 'mg/dL', hasMinMax: true },
{ name: 'albumin', label: 'Albumin', type: 'number', unit: 'g/dL', hasMinMax: true, step: '0.1' },
{ name: 'aniongap', label: 'Anion Gap', type: 'number', unit: 'mEq/L', hasMinMax: true },
{
name: 'bun', label: 'BUN', type: 'number', unit: 'mg/dL', hasMinMax: true,
validation: { normal: { min: 7, max: 20 }, warning: { min: 3, max: 50 }, critical: { min: 0, max: 150 } }
},
{
name: 'creatinine', label: 'Creatinine', type: 'number', unit: 'mg/dL', hasMinMax: true, step: '0.1',
validation: { normal: { min: 0.6, max: 1.2 }, warning: { min: 0.3, max: 5 }, critical: { min: 0, max: 15 } }
},
{ name: 'total_protein', label: 'Total Protein', type: 'number', unit: 'g/dL', hasMinMax: true },
{ name: 'globulin', label: 'Globulin', type: 'number', unit: 'g/dL', hasMinMax: true },
]
},
{
id: 'liver',
label: 'Liver Function',
icon: 'Pill',
description: 'Hepatic function and enzyme levels',
fields: [
{
name: 'alt', label: 'ALT', type: 'number', unit: 'U/L', hasMinMax: true,
validation: { normal: { min: 7, max: 56 }, warning: { min: 0, max: 200 }, critical: { min: 0, max: 1000 } }
},
{
name: 'ast', label: 'AST', type: 'number', unit: 'U/L', hasMinMax: true,
validation: { normal: { min: 10, max: 40 }, warning: { min: 0, max: 200 }, critical: { min: 0, max: 1000 } }
},
{ name: 'alp', label: 'Alkaline Phosphatase', type: 'number', unit: 'U/L', hasMinMax: true },
{ name: 'ggt', label: 'GGT', type: 'number', unit: 'U/L', hasMinMax: true },
{
name: 'bilirubin_total', label: 'Bilirubin (Total)', type: 'number', unit: 'mg/dL', hasMinMax: true, step: '0.1',
validation: { normal: { min: 0.1, max: 1.2 }, warning: { min: 0, max: 5 }, critical: { min: 0, max: 30 } }
},
{ name: 'bilirubin_direct', label: 'Bilirubin (Direct)', type: 'number', unit: 'mg/dL', hasMinMax: true, step: '0.1' },
{ name: 'bilirubin_indirect', label: 'Bilirubin (Indirect)', type: 'number', unit: 'mg/dL', hasMinMax: true, step: '0.1' },
]
},
{
id: 'neuro',
label: 'Neurological',
icon: 'Brain',
description: 'Glasgow Coma Scale and CNS assessment',
fields: [
{
name: 'gcs', label: 'GCS Total', type: 'number', hasMinMax: true,
validation: { normal: { min: 15, max: 15 }, warning: { min: 9, max: 14 }, critical: { min: 3, max: 8 } }
},
{
name: 'gcs_motor', label: 'GCS Motor', type: 'number', hasMinMax: true,
validation: { normal: { min: 6, max: 6 }, warning: { min: 4, max: 5 }, critical: { min: 1, max: 3 } }
},
{
name: 'gcs_verbal', label: 'GCS Verbal', type: 'number', hasMinMax: true,
validation: { normal: { min: 5, max: 5 }, warning: { min: 3, max: 4 }, critical: { min: 1, max: 2 } }
},
{
name: 'gcs_eyes', label: 'GCS Eyes', type: 'number', hasMinMax: true,
validation: { normal: { min: 4, max: 4 }, warning: { min: 3, max: 3 }, critical: { min: 1, max: 2 } }
},
]
},
{
id: 'cardiac',
label: 'Cardiac & Inflammation',
icon: 'Heart',
description: 'Cardiac biomarkers and inflammatory markers',
fields: [
{
name: 'crp', label: 'CRP', type: 'number', unit: 'mg/L', hasMinMax: true,
validation: { normal: { min: 0, max: 10 }, warning: { min: 0, max: 50 }, critical: { min: 0, max: 500 } }
},
{
name: 'urineoutput', label: 'Urine Output', type: 'number', unit: 'mL/hr', hasMinMax: true,
validation: { normal: { min: 30, max: 100 }, warning: { min: 10, max: 200 }, critical: { min: 0, max: 500 } }
},
{ name: 'troponin_t', label: 'Troponin T', type: 'number', unit: 'ng/mL', hasMinMax: true, step: '0.001' },
{ name: 'ck_mb', label: 'CK-MB', type: 'number', unit: 'ng/mL', hasMinMax: true },
{ name: 'ntprobnp', label: 'NT-proBNP', type: 'number', unit: 'pg/mL', hasMinMax: true },
]
},
];
// Get validation status for a value
export function getValidationStatus(field: FieldConfig, value: string): 'normal' | 'warning' | 'critical' | 'invalid' | null {
if (!field.validation || value === '' || value === null || value === undefined) {
return null;
}
const numValue = parseFloat(value);
if (isNaN(numValue)) return null;
const { normal, warning, critical } = field.validation;
// Check if outside critical range (invalid)
if (numValue < critical.min || numValue > critical.max) {
return 'invalid';
}
// Check normal range
if (numValue >= normal.min && numValue <= normal.max) {
return 'normal';
}
// Check warning range
if (numValue >= warning.min && numValue <= warning.max) {
return 'warning';
}
// Outside warning but inside critical = critical
return 'critical';
}
// Helper to generate field keys for form state
export function generateFormFields(): Record<string, any> {
const fields: Record<string, any> = {};
formCategories.forEach(category => {
category.fields.forEach(field => {
// Simplified: Just one field for the input
fields[field.name] = field.type === 'select' && field.options
? field.options[0]?.value
: '';
});
});
return fields;
}
// Helper to prepare payload for API
export function preparePayload(formData: Record<string, any>): Record<string, any> {
const payload: Record<string, any> = {};
// First copy all known fields
Object.entries(formData).forEach(([key, value]) => {
if (value === '' || value === null || value === undefined) {
return;
}
const numValue = parseFloat(value as string);
payload[key] = isNaN(numValue) ? value : numValue;
});
// Now auto-populate min/max if they don't exist
// Loop through all defined categories/fields
formCategories.forEach(category => {
category.fields.forEach(field => {
if (field.hasMinMax) {
const val = formData[field.name];
if (val !== '' && val !== null && val !== undefined) {
const numVal = parseFloat(val);
if (!isNaN(numVal)) {
// Assuming single measurement means min = max = value
payload[`${field.name}_min`] = numVal;
payload[`${field.name}_max`] = numVal;
}
}
}
});
});
return payload;
}