NeoScan_Radiologist/app/modules/Dashboard/screens/ERDashboardScreen.tsx
2025-08-14 20:16:03 +05:30

791 lines
24 KiB
TypeScript

/*
* File: ERDashboardScreen.tsx
* Description: Brain AI Analysis Dashboard - Main dashboard for neurological AI predictions and brain imaging analysis
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
import React, { useState, useEffect } from 'react';
import {
View,
Text,
StyleSheet,
ScrollView,
TouchableOpacity,
RefreshControl,
FlatList,
Alert,
} from 'react-native';
import { theme } from '../../../theme/theme';
import { ERDashboard, Patient, Alert as AlertType } from '../../../shared/types';
import { PatientCard } from '../components/PatientCard';
import { CriticalAlerts } from '../components/CriticalAlerts';
import { DashboardHeader } from '../components/DashboardHeader';
import { BrainPredictionsOverview } from '../components/BrainPredictionsOverview';
/**
* ERDashboardScreenProps Interface
*
* Purpose: Defines the props required by the ERDashboardScreen component
*
* Props:
* - navigation: React Navigation object for screen navigation
*/
interface ERDashboardScreenProps {
navigation: any;
}
/**
* Brain AI Prediction Types
*
* Purpose: Defines the different types of brain conditions that AI can predict
*/
type BrainCondition =
| 'Intraparenchymal hemorrhage (IPH)'
| 'Intraventricular hemorrhage (IVH)'
| 'Subarachnoid hemorrhage (SAH)'
| 'Subdural hematoma (SDH)'
| 'Epidural hematoma (EDH)'
| 'Mass effect'
| 'Midline shift'
| 'Intracranial hemorrhage (ICH)'
| 'Stroke (ischemic)'
| 'Normal brain';
/**
* ERDashboardScreen Component
*
* Purpose: Brain AI Analysis Dashboard for Emergency Department physicians
*
* Dashboard Features:
* 1. Real-time brain scan analysis with AI predictions
* 2. Critical neurological alerts for immediate attention
* 3. Quick action buttons for brain imaging tasks
* 4. Department statistics focused on neurological cases
* 5. Pull-to-refresh functionality for live updates
* 6. AI prediction confidence scores and analysis
*
* Brain Condition Filtering:
* - All: Shows all brain scan cases
* - Critical: Shows only cases with critical brain conditions
* - Pending: Shows cases awaiting AI analysis
*
* AI Prediction Classes:
* - Intraparenchymal hemorrhage (IPH)
* - Intraventricular hemorrhage (IVH)
* - Subarachnoid hemorrhage (SAH)
* - Subdural hematoma (SDH)
* - Epidural hematoma (EDH)
* - Mass effect
* - Midline shift
* - Intracranial hemorrhage (ICH)
* - Stroke (ischemic)
* - Normal brain
*/
export const ERDashboardScreen: React.FC<ERDashboardScreenProps> = ({
navigation,
}) => {
// ============================================================================
// STATE MANAGEMENT
// ============================================================================
// Refresh state for pull-to-refresh functionality
const [refreshing, setRefreshing] = useState(false);
// Patient filter state to control which brain cases are displayed
const [selectedFilter, setSelectedFilter] = useState<'all' | 'critical' | 'pending'>('all');
// Dashboard data state
const [dashboard, setDashboard] = useState<ERDashboard | null>(null);
const [patients, setPatients] = useState<Patient[]>([]);
const [alerts, setAlerts] = useState<AlertType[]>([]);
const [isLoading, setIsLoading] = useState(true);
// ============================================================================
// MOCK DATA GENERATION
// ============================================================================
/**
* generateMockDashboard Function
*
* Purpose: Generate mock dashboard data focused on brain AI analysis
*
* Returns: ERDashboard object with brain imaging statistics
*/
const generateMockDashboard = (): ERDashboard => ({
totalPatients: 18, // Total number of brain scan cases
criticalPatients: 5, // Number of critical brain conditions
pendingScans: 6, // Number of scans awaiting AI analysis
recentReports: 12, // Number of AI analysis reports generated
bedOccupancy: 78, // Percentage of neurological beds occupied
departmentStats: {
emergency: 8, // Emergency brain cases
trauma: 4, // Traumatic brain injury cases
cardiac: 3, // Stroke cases (using cardiac as placeholder)
neurology: 2, // General neurology cases
pediatrics: 1, // Neurosurgery cases (using pediatrics as placeholder)
icu: 0, // ICU brain cases
},
shiftInfo: {
currentShift: 'DAY' as const, // Current shift (DAY/NIGHT)
startTime: new Date(), // Shift start time
endTime: new Date(), // Shift end time
attendingPhysician: 'Dr. Smith', // Lead neurologist on duty
residents: ['Dr. Johnson', 'Dr. Williams'], // Neurology residents
nurses: ['Nurse Brown', 'Nurse Davis'], // Neurology nursing staff
},
lastUpdated: new Date(), // Last time dashboard was updated
});
/**
* generateMockPatients Function
*
* Purpose: Generate mock patient data focused on brain conditions and AI predictions
*
* Returns: Array of Patient objects with brain-related medical data
*/
const generateMockPatients = (): Patient[] => [
{
id: '1',
mrn: 'MRN001',
firstName: 'John',
lastName: 'Doe',
dateOfBirth: new Date('1985-03-15'),
gender: 'MALE' as const,
age: 38,
bedNumber: 'A1',
roomNumber: '101',
admissionDate: new Date('2024-01-15'),
status: 'ACTIVE' as const,
priority: 'CRITICAL' as const,
department: 'Emergency',
attendingPhysician: 'Dr. Smith',
allergies: [
{
id: '1',
name: 'Contrast Dye',
severity: 'SEVERE' as const,
reaction: 'Anaphylaxis'
},
],
medications: [
{
id: '1',
name: 'Mannitol',
dosage: '100ml',
frequency: 'Every 6 hours',
route: 'IV',
startDate: new Date(),
status: 'ACTIVE' as const,
prescribedBy: 'Dr. Smith',
},
],
vitalSigns: {
bloodPressure: { systolic: 180, diastolic: 110, timestamp: new Date() },
heartRate: { value: 95, timestamp: new Date() },
temperature: { value: 37.2, timestamp: new Date() },
respiratoryRate: { value: 18, timestamp: new Date() },
oxygenSaturation: { value: 98, timestamp: new Date() },
},
medicalHistory: [],
currentDiagnosis: 'AI Predicted: Intraparenchymal hemorrhage (IPH) - 94% confidence',
lastUpdated: new Date(),
},
{
id: '2',
mrn: 'MRN002',
firstName: 'Jane',
lastName: 'Smith',
dateOfBirth: new Date('1990-07-22'),
gender: 'FEMALE' as const,
age: 33,
bedNumber: 'B2',
roomNumber: '102',
admissionDate: new Date('2024-01-15'),
status: 'ACTIVE' as const,
priority: 'CRITICAL' as const,
department: 'Trauma',
attendingPhysician: 'Dr. Johnson',
allergies: [],
medications: [
{
id: '2',
name: 'Dexamethasone',
dosage: '4mg',
frequency: 'Every 6 hours',
route: 'IV',
startDate: new Date(),
status: 'ACTIVE' as const,
prescribedBy: 'Dr. Johnson',
},
],
vitalSigns: {
bloodPressure: { systolic: 160, diastolic: 90, timestamp: new Date() },
heartRate: { value: 88, timestamp: new Date() },
temperature: { value: 36.8, timestamp: new Date() },
respiratoryRate: { value: 16, timestamp: new Date() },
oxygenSaturation: { value: 99, timestamp: new Date() },
},
medicalHistory: [],
currentDiagnosis: 'AI Predicted: Subdural hematoma (SDH) with mass effect - 89% confidence',
lastUpdated: new Date(),
},
{
id: '3',
mrn: 'MRN003',
firstName: 'Michael',
lastName: 'Brown',
dateOfBirth: new Date('1978-11-08'),
gender: 'MALE' as const,
age: 45,
bedNumber: 'C3',
roomNumber: '103',
admissionDate: new Date('2024-01-15'),
status: 'PENDING' as const,
priority: 'HIGH' as const,
department: 'Stroke',
attendingPhysician: 'Dr. Williams',
allergies: [
{
id: '2',
name: 'Aspirin',
severity: 'MODERATE' as const,
reaction: 'Stomach upset'
},
],
medications: [
{
id: '3',
name: 'tPA',
dosage: '0.9mg/kg',
frequency: 'Single dose',
route: 'IV',
startDate: new Date(),
status: 'ACTIVE' as const,
prescribedBy: 'Dr. Williams',
},
],
vitalSigns: {
bloodPressure: { systolic: 140, diastolic: 85, timestamp: new Date() },
heartRate: { value: 110, timestamp: new Date() },
temperature: { value: 36.9, timestamp: new Date() },
respiratoryRate: { value: 20, timestamp: new Date() },
oxygenSaturation: { value: 95, timestamp: new Date() },
},
medicalHistory: [],
currentDiagnosis: 'AI Predicted: Stroke (ischemic) - 92% confidence',
lastUpdated: new Date(),
},
{
id: '4',
mrn: 'MRN004',
firstName: 'Sarah',
lastName: 'Wilson',
dateOfBirth: new Date('1995-04-12'),
gender: 'FEMALE' as const,
age: 28,
bedNumber: 'D4',
roomNumber: '104',
admissionDate: new Date('2024-01-15'),
status: 'ACTIVE' as const,
priority: 'CRITICAL' as const,
department: 'Neurosurgery',
attendingPhysician: 'Dr. Davis',
allergies: [],
medications: [
{
id: '4',
name: 'Phenytoin',
dosage: '100mg',
frequency: 'Every 8 hours',
route: 'IV',
startDate: new Date(),
status: 'ACTIVE' as const,
prescribedBy: 'Dr. Davis',
},
],
vitalSigns: {
bloodPressure: { systolic: 190, diastolic: 120, timestamp: new Date() },
heartRate: { value: 60, timestamp: new Date() },
temperature: { value: 38.5, timestamp: new Date() },
respiratoryRate: { value: 12, timestamp: new Date() },
oxygenSaturation: { value: 92, timestamp: new Date() },
},
medicalHistory: [],
currentDiagnosis: 'AI Predicted: Epidural hematoma (EDH) with midline shift - 96% confidence',
lastUpdated: new Date(),
},
{
id: '5',
mrn: 'MRN005',
firstName: 'David',
lastName: 'Miller',
dateOfBirth: new Date('1982-09-30'),
gender: 'MALE' as const,
age: 41,
bedNumber: 'E5',
roomNumber: '105',
admissionDate: new Date('2024-01-15'),
status: 'ACTIVE' as const,
priority: 'HIGH' as const,
department: 'Neurology',
attendingPhysician: 'Dr. Brown',
allergies: [
{
id: '3',
name: 'Latex',
severity: 'SEVERE' as const,
reaction: 'Contact dermatitis'
},
],
medications: [],
vitalSigns: {
bloodPressure: { systolic: 130, diastolic: 80, timestamp: new Date() },
heartRate: { value: 85, timestamp: new Date() },
temperature: { value: 37.8, timestamp: new Date() },
respiratoryRate: { value: 22, timestamp: new Date() },
oxygenSaturation: { value: 97, timestamp: new Date() },
},
medicalHistory: [],
currentDiagnosis: 'AI Predicted: Subarachnoid hemorrhage (SAH) - 87% confidence',
lastUpdated: new Date(),
},
{
id: '6',
mrn: 'MRN006',
firstName: 'Emily',
lastName: 'Johnson',
dateOfBirth: new Date('1988-12-05'),
gender: 'FEMALE' as const,
age: 35,
bedNumber: 'F6',
roomNumber: '106',
admissionDate: new Date('2024-01-15'),
status: 'PENDING' as const,
priority: 'MEDIUM' as const,
department: 'Emergency',
attendingPhysician: 'Dr. Wilson',
allergies: [],
medications: [],
vitalSigns: {
bloodPressure: { systolic: 120, diastolic: 75, timestamp: new Date() },
heartRate: { value: 72, timestamp: new Date() },
temperature: { value: 37.0, timestamp: new Date() },
respiratoryRate: { value: 16, timestamp: new Date() },
oxygenSaturation: { value: 99, timestamp: new Date() },
},
medicalHistory: [],
currentDiagnosis: 'AI Analysis Pending - CT scan uploaded',
lastUpdated: new Date(),
},
];
/**
* generateMockAlerts Function
*
* Purpose: Generate mock alert data focused on brain AI predictions
*
* Returns: Array of Alert objects with brain-related alerts
*/
const generateMockAlerts = (): AlertType[] => [
{
id: '1',
type: 'CRITICAL_FINDING' as const,
priority: 'CRITICAL' as const,
title: 'Critical Brain Finding Detected',
message: 'AI has detected Intraparenchymal hemorrhage (IPH) with 94% confidence. Immediate neurosurgical consultation required.',
patientId: '1',
patientName: 'John Doe',
bedNumber: 'A1',
timestamp: new Date(),
isRead: false,
isAcknowledged: false,
actionRequired: true,
},
{
id: '2',
type: 'VITAL_SIGNS_ALERT' as const,
priority: 'HIGH' as const,
title: 'Elevated ICP Alert',
message: 'Patient Sarah Wilson showing signs of elevated intracranial pressure. BP: 190/120, HR: 60. Immediate intervention needed.',
patientId: '4',
patientName: 'Sarah Wilson',
bedNumber: 'D4',
timestamp: new Date(Date.now() - 300000), // 5 minutes ago
isRead: false,
isAcknowledged: false,
actionRequired: true,
},
{
id: '3',
type: 'MEDICATION_ALERT' as const,
priority: 'MEDIUM' as const,
title: 'AI Analysis Complete',
message: 'Brain CT analysis complete for Emily Johnson. Results: Normal brain - 98% confidence. No intervention required.',
patientId: '6',
patientName: 'Emily Johnson',
bedNumber: 'F6',
timestamp: new Date(Date.now() - 600000), // 10 minutes ago
isRead: true,
isAcknowledged: true,
actionRequired: false,
},
{
id: '4',
type: 'CRITICAL_FINDING' as const,
priority: 'CRITICAL' as const,
title: 'Stroke Alert - Time Sensitive',
message: 'Michael Brown diagnosed with ischemic stroke. tPA window closing. Immediate thrombolytic therapy required.',
patientId: '3',
patientName: 'Michael Brown',
bedNumber: 'C3',
timestamp: new Date(Date.now() - 120000), // 2 minutes ago
isRead: false,
isAcknowledged: false,
actionRequired: true,
},
];
// ============================================================================
// EFFECTS
// ============================================================================
/**
* useEffect for initial data loading
*
* Purpose: Load initial mock data when component mounts
*/
useEffect(() => {
const loadInitialData = async () => {
setIsLoading(true);
// Simulate API call delay
setTimeout(() => {}, 1000);
// Generate and set mock data
setDashboard(generateMockDashboard());
setPatients(generateMockPatients());
setAlerts(generateMockAlerts());
setIsLoading(false);
};
loadInitialData();
}, []);
// ============================================================================
// EVENT HANDLERS
// ============================================================================
/**
* handleRefresh Function
*
* Purpose: Handle pull-to-refresh functionality to update dashboard data
*/
const handleRefresh = async () => {
setRefreshing(true);
// Simulate API call with 1-second delay
setTimeout(() => {}, 1000);
// Update data with fresh mock data
setDashboard(generateMockDashboard());
setPatients(generateMockPatients());
setAlerts(generateMockAlerts());
setRefreshing(false);
};
/**
* handlePatientPress Function
*
* Purpose: Handle patient card press navigation
*
* @param patient - Patient object that was pressed
*/
const handlePatientPress = (patient: Patient) => {
console.log('Patient pressed:', patient.firstName, patient.lastName);
Alert.alert('Brain Analysis Details', `Navigate to ${patient.firstName} ${patient.lastName}'s brain scan analysis`);
};
/**
* handleAlertPress Function
*
* Purpose: Handle alert press interaction
*
* @param alert - Alert object that was pressed
*/
const handleAlertPress = (alert: AlertType) => {
console.log('Alert pressed:', alert.title);
Alert.alert('Brain Alert Details', alert.message);
};
// ============================================================================
// DATA PROCESSING
// ============================================================================
/**
* filteredPatients - Computed property
*
* Purpose: Filter patients based on selected filter criteria
*
* Filter Options:
* - 'all': Show all brain scan cases
* - 'critical': Show only cases with CRITICAL priority
* - 'pending': Show only cases with PENDING status (awaiting AI analysis)
*/
const filteredPatients = patients.filter(patient => {
switch (selectedFilter) {
case 'critical':
return patient.priority === 'CRITICAL';
case 'pending':
return patient.status === 'PENDING';
default:
return true;
}
});
/**
* criticalAlerts - Computed property
*
* Purpose: Extract critical alerts from all alerts for immediate display
*/
const criticalAlerts = alerts.filter(alert => alert.priority === 'CRITICAL');
/**
* pendingScans - Computed property
*
* Purpose: Identify patients with pending AI analysis
*/
const pendingScans = patients.filter(patient => patient.status === 'PENDING');
// ============================================================================
// RENDER FUNCTIONS
// ============================================================================
/**
* renderPatientCard Function
*
* Purpose: Render individual patient card component
*
* @param item - Patient data object
* @returns PatientCard component with patient data and press handler
*/
const renderPatientCard = ({ item }: { item: Patient }) => (
<PatientCard
patient={item}
onPress={() => handlePatientPress(item)}
/>
);
/**
* renderHeader Function
*
* Purpose: Render the dashboard header section with all dashboard components
*/
const renderHeader = () => (
<View style={styles.header}>
{/* Dashboard header with shift information and key metrics */}
{dashboard && <DashboardHeader dashboard={dashboard} />}
{/* Critical alerts section - only show if there are critical alerts */}
{criticalAlerts.length > 0 && (
<CriticalAlerts
alerts={criticalAlerts}
onAlertPress={handleAlertPress}
/>
)}
{/* Department statistics showing brain case distribution */}
{dashboard && <BrainPredictionsOverview dashboard={dashboard} />}
{/* Brain case filter section with filter buttons */}
<View style={styles.filterContainer}>
<Text style={styles.sectionTitle}>Brain Scan Cases</Text>
<View style={styles.filterButtons}>
{/* All cases filter button */}
<TouchableOpacity
style={[
styles.filterButton,
selectedFilter === 'all' && styles.filterButtonActive
]}
onPress={() => setSelectedFilter('all')}
>
<Text style={[
styles.filterButtonText,
selectedFilter === 'all' && styles.filterButtonTextActive
]}>
All ({patients.length})
</Text>
</TouchableOpacity>
{/* Critical cases filter button */}
<TouchableOpacity
style={[
styles.filterButton,
selectedFilter === 'critical' && styles.filterButtonActive
]}
onPress={() => setSelectedFilter('critical')}
>
<Text style={[
styles.filterButtonText,
selectedFilter === 'critical' && styles.filterButtonTextActive
]}>
Critical ({patients.filter(p => p.priority === 'CRITICAL').length})
</Text>
</TouchableOpacity>
{/* Pending AI analysis filter button */}
<TouchableOpacity
style={[
styles.filterButton,
selectedFilter === 'pending' && styles.filterButtonActive
]}
onPress={() => setSelectedFilter('pending')}
>
<Text style={[
styles.filterButtonText,
selectedFilter === 'pending' && styles.filterButtonTextActive
]}>
Pending AI ({patients.filter(p => p.status === 'PENDING').length})
</Text>
</TouchableOpacity>
</View>
</View>
</View>
);
// ============================================================================
// LOADING STATE
// ============================================================================
/**
* Loading state render
*
* Purpose: Show loading indicator while data is being generated
*/
if (isLoading) {
return (
<View style={styles.loadingContainer}>
<Text style={styles.loadingText}>Loading Brain AI Dashboard...</Text>
</View>
);
}
// ============================================================================
// MAIN RENDER
// ============================================================================
return (
<View style={styles.container}>
{/* FlatList for efficient rendering of patient cards */}
<FlatList
data={filteredPatients}
renderItem={renderPatientCard}
keyExtractor={(item) => item.id}
ListHeaderComponent={renderHeader}
contentContainerStyle={styles.listContainer}
refreshControl={
<RefreshControl
refreshing={refreshing}
onRefresh={handleRefresh}
colors={[theme.colors.primary]}
tintColor={theme.colors.primary}
/>
}
showsVerticalScrollIndicator={false}
/>
</View>
);
};
// ============================================================================
// STYLES SECTION
// ============================================================================
const styles = StyleSheet.create({
// Main container for the dashboard screen
container: {
flex: 1,
backgroundColor: theme.colors.background,
},
// Loading container for initial data loading
loadingContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: theme.colors.background,
},
// Loading text styling
loadingText: {
fontSize: theme.typography.fontSize.bodyLarge,
color: theme.colors.textSecondary,
fontFamily: theme.typography.fontFamily.medium,
},
// Container for the FlatList content
listContainer: {
paddingBottom: theme.spacing.lg,
},
// Header section containing dashboard components
header: {
paddingHorizontal: theme.spacing.md,
},
// Container for patient filter section
filterContainer: {
marginTop: theme.spacing.lg,
marginBottom: theme.spacing.md,
},
// Section title styling
sectionTitle: {
fontSize: theme.typography.fontSize.displaySmall,
fontFamily: theme.typography.fontFamily.bold,
color: theme.colors.textPrimary,
marginBottom: theme.spacing.md,
},
// Container for filter buttons
filterButtons: {
flexDirection: 'row',
gap: theme.spacing.sm,
},
// Individual filter button styling
filterButton: {
paddingHorizontal: theme.spacing.md,
paddingVertical: theme.spacing.sm,
borderRadius: theme.borderRadius.medium,
borderWidth: 1,
borderColor: theme.colors.border,
backgroundColor: theme.colors.background,
},
// Active filter button styling
filterButtonActive: {
backgroundColor: theme.colors.primary,
borderColor: theme.colors.primary,
},
// Filter button text styling
filterButtonText: {
fontSize: theme.typography.fontSize.bodyMedium,
color: theme.colors.textSecondary,
fontFamily: theme.typography.fontFamily.medium,
},
// Active filter button text styling
filterButtonTextActive: {
color: theme.colors.background,
},
});
/*
* End of File: ERDashboardScreen.tsx
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/