/* * File: DashboardScreen.tsx * Description: Main dashboard screen with a custom header and themed components. * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */ import React, { useEffect, useState, useMemo } from 'react'; import { View, Text, StyleSheet, ScrollView } from 'react-native'; import { Button } from '../../../../shared/src/components/Button'; import { Card, InfoCard } from '../../../../shared/src/components/Card'; import { TextInput, SearchInput } from '../../../../shared/src/components/Input'; import { Modal, ConfirmModal, AlertModal } from '../../../../shared/src/components/Modal'; import { Spinner, LoadingOverlay } from '../../../../shared/src/components/Loading'; import { CustomIcon, IconButton } from '../../../../shared/src/components/Icons'; import { CustomHeader } from '../../../../shared/src/components/Header'; import { Colors, Spacing, Typography } from '../../../../shared/src/theme'; import { useDispatch, useSelector } from 'react-redux'; import { fetchPatients, selectPatients } from '../redux'; interface PatientDetails { Date: string; Name: string; PatID: string; PatAge: string; PatSex: string; Status: string; InstName: string; Modality: 'DX' | 'CT' | 'MR'; ReportStatus: string | null; } interface Series { Path: string[]; SerDes: string; ViePos: string | null; pngpath: string; SeriesNum: string; ImgTotalinSeries: string; } export interface MedicalCase { id: number; patientdetails: PatientDetails; series: Series[]; created_at: string; updated_at: string; series_id: string | null; type: 'Critical' | 'Routine' | 'Emergency'; } interface CaseStats { total: number; modalityCounts: { DX: number; CT: number; MR: number; }; } /** * DashboardScreen - The primary landing screen after login, featuring a custom header, * case summaries, and navigation to other parts of the app. */ const DashboardScreen: React.FC<{ navigation: any }> = ({ navigation }) => { const [modalVisible, setModalVisible] = useState(false); const [confirmVisible, setConfirmVisible] = useState(false); const [alertVisible, setAlertVisible] = useState(false); const [loading, setLoading] = useState(false); const [search, setSearch] = useState(''); const [input, setInput] = useState(''); const [selectedCase, setSelectedCase] = useState(null); const dispatch = useDispatch(); const { access_token, display_name } = useSelector((state: any) => state.auth.user); const patientData: MedicalCase[] = useSelector(selectPatients) || []; useEffect(() => { //@ts-ignore dispatch(fetchPatients(access_token)); }, []); // Filter cases based on search const filteredCases = useMemo(() => { if (!search.trim()) return patientData; return patientData.filter(case_ => case_.patientdetails.Name.toLowerCase().includes(search.toLowerCase()) || case_.patientdetails.PatID.toLowerCase().includes(search.toLowerCase()) || case_.patientdetails.InstName.toLowerCase().includes(search.toLowerCase()) ); }, [patientData, search]); // Calculate statistics for each case type const caseStats = useMemo(() => { const stats: Record = { Critical: { total: 0, modalityCounts: { DX: 0, CT: 0, MR: 0 } }, Routine: { total: 0, modalityCounts: { DX: 0, CT: 0, MR: 0 } }, Emergency: { total: 0, modalityCounts: { DX: 0, CT: 0, MR: 0 } } }; filteredCases.forEach(case_ => { const type = case_.type; const modality = case_.patientdetails.Modality; stats[type].total += 1; stats[type].modalityCounts[modality?.substring(1)] += 1; }); return stats; }, [filteredCases]); const getCaseIcon = (type: string) => { switch (type) { case 'Critical': return { name: 'alert', color: Colors.error }; case 'Emergency': return { name: 'alert', color: '#FF8C00' }; // Orange color for emergency case 'Routine': return { name: 'check-circle', color: Colors.success }; default: return { name: 'info', color: Colors.primary }; } }; const getCaseColor = (type: string) => { switch (type) { case 'Critical': return Colors.error; case 'Emergency': return '#FF8C00'; // Orange case 'Routine': return Colors.success; default: return Colors.textSecondary; } }; const handleCasePress = (type: string) => { const casesOfType = filteredCases.filter(case_ => case_.type === type); if (casesOfType.length > 0) { navigation.navigate('DashboardDetailScreen',{caseType:type}) // setSelectedCase(casesOfType[0]); // setModalVisible(true); } }; const renderCaseCard = (type: 'Critical' | 'Routine' | 'Emergency') => { const stats = caseStats[type]; const icon = getCaseIcon(type); const color = getCaseColor(type); if (stats.total === 0) return null; // Don't render card if no cases of this type console.log('counts data',stats.modalityCounts) return ( {type} Cases {stats.total} Total By Modality: {(['DX', 'CT', 'MR'] as const).map(modality => ( {modality} {stats.modalityCounts[modality]} ))}