/* * File: PatientCard.tsx * Description: Patient card component displaying patient information and status * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */ import React from 'react'; import { View, Text, TouchableOpacity, StyleSheet, } from 'react-native'; import { theme } from '../../../theme/theme'; import { Patient } from '../../../shared/types/patient'; import { getPriorityColor, getStatusColor, calculateAge } from '../../../shared/utils/helpers'; /** * PatientCardProps Interface * * Purpose: Defines the props required by the PatientCard component * * Props: * - patient: Patient data object containing all patient information * - onPress: Callback function triggered when the card is pressed */ interface PatientCardProps { patient: Patient; onPress: (patient: Patient) => void; } /** * PatientCard Component * * Purpose: Display comprehensive patient information in a compact, touchable card format * * Features: * 1. Patient identification (name, age, gender, MRN) * 2. Priority and status badges with color coding * 3. Location information (bed, room, attending physician) * 4. Real-time vital signs display * 5. Allergy warnings (if any) * 6. Current diagnosis and last update time * * Data Display: * - Header: Patient name, demographics, and status badges * - Location: Bed/room assignment and attending physician * - Vital Signs: BP, HR, Temperature, Oxygen saturation * - Allergies: Warning display for known allergies * - Footer: Current diagnosis and timestamp * * Interaction: * - Touchable card that navigates to detailed patient view * - Visual feedback with activeOpacity for better UX */ export const PatientCard: React.FC = ({ patient, onPress, }) => { // ============================================================================ // DATA PROCESSING // ============================================================================ // Calculate patient age from date of birth const age = calculateAge(patient.dateOfBirth); // Get color coding for priority and status badges const priorityColor = getPriorityColor(patient.priority); // Color based on priority level const statusColor = getStatusColor(patient.status); // Color based on patient status /** * formatVitalSigns Function * * Purpose: Format vital signs data for display in the card * * Returns: * - bp: Blood pressure in systolic/diastolic format * - hr: Heart rate value * - temp: Temperature in Celsius * - o2: Oxygen saturation percentage */ const formatVitalSigns = () => { const { vitalSigns } = patient; return { bp: `${vitalSigns.bloodPressure.systolic}/${vitalSigns.bloodPressure.diastolic}`, // Format: 120/80 hr: vitalSigns.heartRate.value, // Heart rate: 75 temp: vitalSigns.temperature.value, // Temperature: 37.2 o2: vitalSigns.oxygenSaturation.value, // Oxygen: 98 }; }; // Format vital signs for display const vitals = formatVitalSigns(); // ============================================================================ // RENDER SECTION // ============================================================================ return ( onPress(patient)} // Navigate to patient details activeOpacity={0.7} // Visual feedback on touch > {/* ======================================================================== * HEADER SECTION - Patient identification and status badges * ======================================================================== */} {/* Patient information section */} {/* Patient full name */} {patient.firstName} {patient.lastName} {/* Patient demographics and MRN */} {age} years • {patient.gender} • MRN: {patient.mrn} {/* Status badges section */} {/* Priority badge with color coding */} {patient.priority} {/* Status badge with color coding */} {patient.status} {/* ======================================================================== * LOCATION SECTION - Bed assignment and attending physician * ======================================================================== */} {/* Bed and room location */} Bed {patient.bedNumber} • Room {patient.roomNumber} {/* Attending physician */} Dr. {patient.attendingPhysician} {/* ======================================================================== * VITAL SIGNS SECTION - Real-time patient vitals * ======================================================================== */} {/* Blood Pressure */} BP {vitals.bp} {/* Heart Rate */} HR {vitals.hr} {/* Temperature */} Temp {vitals.temp}°C {/* Oxygen Saturation */} O₂ {vitals.o2}% {/* ======================================================================== * ALLERGIES SECTION - Warning display for known allergies * ======================================================================== */} {patient.allergies.length > 0 && ( Allergies: {patient.allergies.map(a => a.name).join(', ')} )} {/* ======================================================================== * FOOTER SECTION - Diagnosis and last update time * ======================================================================== */} {/* Current diagnosis */} {patient.currentDiagnosis} {/* Last update timestamp */} Updated {new Date(patient.lastUpdated).toLocaleTimeString()} ); }; // ============================================================================ // STYLES SECTION // ============================================================================ const styles = StyleSheet.create({ // Main card container with shadow and rounded corners container: { backgroundColor: theme.colors.cardBackground, borderRadius: theme.borderRadius.large, padding: theme.spacing.md, marginHorizontal: theme.spacing.md, marginVertical: theme.spacing.sm, ...theme.shadows.small, // Add subtle shadow for elevation }, // Header section with patient info and badges header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: theme.spacing.sm, }, // Patient information container patientInfo: { flex: 1, // Take available space }, // Patient name styling patientName: { fontSize: theme.typography.fontSize.bodyLarge, fontFamily: theme.typography.fontFamily.bold, color: theme.colors.textPrimary, marginBottom: theme.spacing.xs, }, // Patient details styling (age, gender, MRN) patientDetails: { fontSize: theme.typography.fontSize.bodySmall, color: theme.colors.textSecondary, }, // Badges container for priority and status badges: { flexDirection: 'row', gap: theme.spacing.xs, // Space between badges }, // Individual badge styling badge: { paddingHorizontal: theme.spacing.sm, paddingVertical: theme.spacing.xs, borderRadius: theme.borderRadius.small, }, // Badge text styling badgeText: { fontSize: theme.typography.fontSize.caption, fontFamily: theme.typography.fontFamily.medium, }, // Location information container locationInfo: { marginBottom: theme.spacing.sm, }, // Bed and room location text locationText: { fontSize: theme.typography.fontSize.bodyMedium, color: theme.colors.textPrimary, fontFamily: theme.typography.fontFamily.medium, }, // Attending physician text attendingText: { fontSize: theme.typography.fontSize.bodySmall, color: theme.colors.textSecondary, }, // Vital signs container with background vitalSigns: { flexDirection: 'row', justifyContent: 'space-between', backgroundColor: theme.colors.backgroundAccent, // Light background for vitals borderRadius: theme.borderRadius.medium, padding: theme.spacing.sm, marginBottom: theme.spacing.sm, }, // Individual vital sign item vitalItem: { alignItems: 'center', // Center align label and value }, // Vital sign label (BP, HR, Temp, O₂) vitalLabel: { fontSize: theme.typography.fontSize.caption, color: theme.colors.textSecondary, fontFamily: theme.typography.fontFamily.medium, marginBottom: theme.spacing.xs, }, // Vital sign value styling vitalValue: { fontSize: theme.typography.fontSize.bodyMedium, color: theme.colors.textPrimary, fontFamily: theme.typography.fontFamily.bold, }, // Allergies container allergiesContainer: { marginBottom: theme.spacing.sm, }, // Allergies label with warning color allergiesLabel: { fontSize: theme.typography.fontSize.bodySmall, color: theme.colors.warning, // Warning color for allergies fontFamily: theme.typography.fontFamily.medium, marginBottom: theme.spacing.xs, }, // Allergies text listing allergiesText: { fontSize: theme.typography.fontSize.bodySmall, color: theme.colors.textSecondary, }, // Footer container with diagnosis and timestamp footer: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', }, // Current diagnosis text diagnosisText: { fontSize: theme.typography.fontSize.bodyMedium, color: theme.colors.textPrimary, fontFamily: theme.typography.fontFamily.medium, flex: 1, // Take available space }, // Last update timestamp timeText: { fontSize: theme.typography.fontSize.caption, color: theme.colors.textMuted, }, }); /* * End of File: PatientCard.tsx * Design & Developed by Tech4Biz Solutions * Copyright (c) Spurrin Innovations. All rights reserved. */