/* * File: DashboardScreen.tsx * Description: Sample dashboard screen using Clinical Blue Interface and shared components * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */ import React, { useState, useMemo } from 'react'; import { View, Text, StyleSheet, ScrollView, TouchableOpacity, Dimensions } from 'react-native'; import { Button } from '../../../../shared/src/components/Button'; import { Card, InfoCard } from '../../../../shared/src/components/Card'; import { SearchInput } from '../../../../shared/src/components/Input'; import { Modal } from '../../../../shared/src/components/Modal'; import { CustomIcon, IconButton } from '../../../../shared/src/components/Icons'; import { CustomHeader } from '../../../../shared/src/components/Header'; import { Colors, Spacing, Typography } from '../../../../shared/src/theme'; import { useSelector } from 'react-redux'; import { 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 DashBoardDetailProps { navigation: any; route: { params: { caseType: 'Critical' | 'Routine' | 'Emergency'; }; }; } /** * DashBoardDetail - Shows detailed list of patients for a specific case type */ const DashBoardDetail: React.FC = ({ navigation, route }) => { const [search, setSearch] = useState(''); const [selectedPatient, setSelectedPatient] = useState(null); const [modalVisible, setModalVisible] = useState(false); const [sortBy, setSortBy] = useState<'date' | 'name' | 'age'>('date'); const caseType = route.params?.caseType || 'Critical'; const patientData: MedicalCase[] = useSelector(selectPatients) || []; // Filter patients by case type and search const filteredPatients = useMemo(() => { let filtered = patientData.filter(case_ => case_.type === caseType); if (search.trim()) { filtered = filtered.filter(case_ => case_.patientdetails.Name.toLowerCase().includes(search.toLowerCase()) || case_.patientdetails.PatID.toLowerCase().includes(search.toLowerCase()) || case_.patientdetails.InstName.toLowerCase().includes(search.toLowerCase()) ); } // Sort patients return filtered.sort((a, b) => { switch (sortBy) { case 'name': return a.patientdetails.Name.localeCompare(b.patientdetails.Name); case 'age': return parseInt(b.patientdetails.PatAge) - parseInt(a.patientdetails.PatAge); case 'date': default: return new Date(b.created_at).getTime() - new Date(a.created_at).getTime(); } }); }, [patientData, caseType, search, sortBy]); const getCaseTypeConfig = (type: string) => { switch (type) { case 'Critical': return { color: Colors.error, icon: 'alert-circle', bgColor: '#FFF5F5' // Light red background }; case 'Emergency': return { color: '#FF8C00', icon: 'alert', bgColor: '#FFF8E1' // Light orange background }; case 'Routine': return { color: Colors.success, icon: 'check-circle', bgColor: '#F0FFF4' // Light green background }; default: return { color: Colors.primary, icon: 'info', bgColor: Colors.background }; } }; const typeConfig = getCaseTypeConfig(caseType); const handlePatientPress = (patient: MedicalCase) => { setSelectedPatient(patient); setModalVisible(true); }; const formatDate = (dateString: string) => { return new Date(dateString).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric', hour: '2-digit', minute: '2-digit' }); }; const getModalityColor = (modality: string) => { switch (modality) { case 'CT': return '#4A90E2'; case 'MR': return '#7B68EE'; case 'DX': return '#50C878'; default: return Colors.textSecondary; } }; const renderPatientCard = (patient: MedicalCase) => ( handlePatientPress(patient)} activeOpacity={0.7} > {patient.patientdetails.Name} ID: {patient.patientdetails.PatID} Age {patient.patientdetails.PatAge} Sex {patient.patientdetails.PatSex} Modality {patient.patientdetails.Modality?.substring(1)} {patient.patientdetails.InstName} {formatDate(patient.created_at)} {patient.patientdetails.Status} {patient.series.length} Series Available handlePatientPress(patient)} /> ); return ( navigation.goBack()} /> {/* Summary Card */} {caseType} Cases {filteredPatients.length} Patient{filteredPatients.length !== 1 ? 's' : ''} {/* Search and Sort */} Sort by: {(['date', 'name', 'age'] as const).map(option => ( setSortBy(option)} > {option.charAt(0).toUpperCase() + option.slice(1)} ))} {/* Patient List */} {filteredPatients.length > 0 ? ( filteredPatients.map(renderPatientCard) ) : ( No {caseType.toLowerCase()} cases found {search ? 'Try adjusting your search terms' : 'All clear for now!'} )} {/* Patient Detail Modal */} setModalVisible(false)} > {selectedPatient && ( Patient Details Basic Information Name: {selectedPatient.patientdetails.Name} ID: {selectedPatient.patientdetails.PatID} Age: {selectedPatient.patientdetails.PatAge} Sex: {selectedPatient.patientdetails.PatSex} Status: {selectedPatient.patientdetails.Status} Medical Information Modality: {selectedPatient.patientdetails.Modality} Institution: {selectedPatient.patientdetails.InstName} Report Status: {selectedPatient.patientdetails.ReportStatus || 'Pending'} Case Type: {selectedPatient.type} Series Information Available Series: {selectedPatient.series.length} Created: {formatDate(selectedPatient.created_at)} Updated: {formatDate(selectedPatient.updated_at)}