Changeset 9af201e for frontend/src/pages/medical-records
- Timestamp:
- 09/04/26 19:08:08 (3 weeks ago)
- Branches:
- master
- Children:
- cdcff72
- Parents:
- e1f74f6
- Location:
- frontend/src/pages/medical-records
- Files:
-
- 2 edited
-
MedicalRecordDetail.js (modified) (5 diffs)
-
MedicalRecordList.js (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
frontend/src/pages/medical-records/MedicalRecordDetail.js
re1f74f6 r9af201e 1 import React, { useState, useEffect } from 'react';1 import React, { useState, useEffect, useCallback } from 'react'; 2 2 import { useParams, useNavigate } from 'react-router-dom'; 3 3 import { medicalRecordService } from '../../services/medicalRecordService'; … … 77 77 const [procedureResults, setProcedureResults] = useState([]); 78 78 79 useEffect(() => { 80 fetchRecord(); 81 fetchDoctors(); 82 fetchDropdownOptions(); 83 }, [id]); 84 85 const fetchDropdownOptions = async () => { 86 try { 87 console.log('Fetching dropdown options...'); 88 const diagnosesRes = await apiClient.get('/medical-records/dropdown/diagnoses'); 89 console.log('Diagnoses:', diagnosesRes.data); 90 91 const symptomsRes = await apiClient.get('/medical-records/dropdown/symptoms'); 92 console.log('Symptoms:', symptomsRes.data); 93 94 const allergiesRes = await apiClient.get('/medical-records/dropdown/allergies'); 95 console.log('Allergies:', allergiesRes.data); 96 97 const prescriptionsRes = await apiClient.get('/medical-records/dropdown/prescriptions'); 98 console.log('Prescriptions:', prescriptionsRes.data); 99 100 const testsRes = await labService.getAllLabTests(); 101 console.log('Lab Tests:', testsRes.data); 102 103 const proceduresRes = await procedureService.getAllProcedures(); 104 console.log('Procedures:', proceduresRes.data); 105 106 setDiagnoses(diagnosesRes.data || []); 107 setSymptoms(symptomsRes.data || []); 108 setAllergies(allergiesRes.data || []); 109 setPrescriptions(prescriptionsRes.data || []); 110 setLabTests(testsRes.data || []); 111 setProcedures(proceduresRes.data || []); 112 console.log('Dropdown options set successfully'); 113 } catch (err) { 114 console.error('Error fetching dropdown options:', err); 115 setError('Failed to load dropdown options: ' + (err.response?.data?.error || err.message)); 116 } 117 }; 118 119 const fetchRecord = async () => { 79 const fetchRecord = useCallback(async () => { 120 80 try { 121 81 setLoading(true); … … 146 106 setLoading(false); 147 107 } 148 }; 149 150 const fetchDoctors = async () => { 151 try { 152 if (!isDoctor) { 153 const response = await doctorService.getAllDoctors(); 154 setDoctors(response.data); 155 if (response.data.length > 0 && !selectedDoctorId) { 156 setSelectedDoctorId(response.data[0].doctorId); 108 }, [id]); 109 110 useEffect(() => { 111 const fetchDoctors = async () => { 112 try { 113 if (!isDoctor) { 114 const response = await doctorService.getAllDoctors(); 115 setDoctors(response.data); 116 if (response.data.length > 0 && !selectedDoctorId) { 117 setSelectedDoctorId(response.data[0].doctorId); 118 } 157 119 } 158 } 159 } catch (err) { 160 console.error('Failed to fetch doctors', err); 161 } 162 }; 120 } catch (err) { 121 console.error('Failed to fetch doctors', err); 122 } 123 }; 124 125 const fetchDropdownOptions = async () => { 126 try { 127 console.log('Fetching dropdown options...'); 128 const diagnosesRes = await apiClient.get('/medical-records/dropdown/diagnoses'); 129 console.log('Diagnoses:', diagnosesRes.data); 130 131 const symptomsRes = await apiClient.get('/medical-records/dropdown/symptoms'); 132 console.log('Symptoms:', symptomsRes.data); 133 134 const allergiesRes = await apiClient.get('/medical-records/dropdown/allergies'); 135 console.log('Allergies:', allergiesRes.data); 136 137 const prescriptionsRes = await apiClient.get('/medical-records/dropdown/prescriptions'); 138 console.log('Prescriptions:', prescriptionsRes.data); 139 140 const testsRes = await labService.getAllLabTests(); 141 console.log('Lab Tests:', testsRes.data); 142 143 const proceduresRes = await procedureService.getAllProcedures(); 144 console.log('Procedures:', proceduresRes.data); 145 146 setDiagnoses(diagnosesRes.data || []); 147 setSymptoms(symptomsRes.data || []); 148 setAllergies(allergiesRes.data || []); 149 setPrescriptions(prescriptionsRes.data || []); 150 setLabTests(testsRes.data || []); 151 setProcedures(proceduresRes.data || []); 152 console.log('Dropdown options set successfully'); 153 } catch (err) { 154 console.error('Error fetching dropdown options:', err); 155 setError('Failed to load dropdown options: ' + (err.response?.data?.error || err.message)); 156 } 157 }; 158 159 fetchRecord(); 160 fetchDoctors(); 161 fetchDropdownOptions(); 162 }, [id, isDoctor, fetchRecord, selectedDoctorId]); 163 163 164 164 const handleAddDiagnosis = async (e) => { … … 857 857 try { 858 858 setLoading(true); 859 const doctorId = localStorage.getItem('doctorId')|| 1;859 const doctorId = user.doctorId || 1; 860 860 861 861 const request = { … … 964 964 try { 965 965 setLoading(true); 966 const doctorId = localStorage.getItem('doctorId')|| 1;966 const doctorId = user.doctorId || 1; 967 967 968 968 const request = { -
frontend/src/pages/medical-records/MedicalRecordList.js
re1f74f6 r9af201e 23 23 const [loading, setLoading] = useState(false); 24 24 25 25 // Auto-load patient's own records if logged in as patient, or load specific patient records if patientId is provided 26 26 React.useEffect(() => { 27 if (patientId) { 28 29 loadPatientRecords(patientId); 30 } else if (isPatient && user.username) { 31 handleAutoSearch(); 32 } 33 }, [patientId]); 34 35 const loadPatientRecords = async (pId) => { 27 const loadPatientRecords = async (pId) => { 36 28 setError(null); 37 29 setLoading(true); 38 30 39 31 try { 40 // Get patient by id32 // Get patient by ID 41 33 const patientResponse = await patientService.getPatientById(pId); 42 34 setPatient(patientResponse.data); … … 73 65 setLoading(false); 74 66 } 75 }; 76 77 const handleAutoSearch = async () => { 78 const searchEmbg = user.username; 79 setError(null); 80 setLoading(true); 81 82 try { 83 // Search patient by EMBG 84 const patientResponse = await patientService.getPatientByEmbg(searchEmbg); 85 setPatient(patientResponse.data); 86 87 // Get medical records for this patient 88 const recordsResponse = await medicalRecordService.getMedicalRecordByPatientId(patientResponse.data.patientId); 89 setMedicalData(recordsResponse.data); 90 91 // Get lab results 67 }; 68 69 const handleAutoSearch = async () => { 70 const searchEmbg = user.username; 71 setError(null); 72 setLoading(true); 73 92 74 try { 93 const labRes = await labService.getLabResultsForMedicalRecord(recordsResponse.data.recordId); 94 setLabResults(labRes.data || []); 75 // Search patient by EMBG 76 const patientResponse = await patientService.getPatientByEmbg(searchEmbg); 77 setPatient(patientResponse.data); 78 79 // Get medical records for this patient 80 const recordsResponse = await medicalRecordService.getMedicalRecordByPatientId(patientResponse.data.patientId); 81 setMedicalData(recordsResponse.data); 82 83 // Get lab results 84 try { 85 const labRes = await labService.getLabResultsForMedicalRecord(recordsResponse.data.recordId); 86 setLabResults(labRes.data || []); 87 } catch (err) { 88 setLabResults([]); 89 } 90 91 // Get procedure results 92 try { 93 const procRes = await procedureService.getProcedureResultsForMedicalRecord(recordsResponse.data.recordId); 94 setProcedureResults(procRes.data || []); 95 } catch (err) { 96 setProcedureResults([]); 97 } 98 99 setSearched(true); 95 100 } catch (err) { 101 setError(`Patient with EMBG ${searchEmbg} not found`); 102 setSearched(true); 103 setPatient(null); 104 setMedicalData(null); 96 105 setLabResults([]); 97 }98 99 // Get procedure results100 try {101 const procRes = await procedureService.getProcedureResultsForMedicalRecord(recordsResponse.data.recordId);102 setProcedureResults(procRes.data || []);103 } catch (err) {104 106 setProcedureResults([]); 105 } 106 107 setSearched(true); 108 } catch (err) { 109 setError(`Patient with EMBG ${searchEmbg} not found`); 110 setSearched(true); 111 setPatient(null); 112 setMedicalData(null); 113 setLabResults([]); 114 setProcedureResults([]); 115 } finally { 116 setLoading(false); 107 } finally { 108 setLoading(false); 109 } 110 }; 111 112 // Call appropriate function based on conditions 113 if (patientId) { 114 loadPatientRecords(patientId); 115 } else if (isPatient && user.username) { 116 handleAutoSearch(); 117 117 } 118 } ;118 }, [patientId, isPatient, user.username]); 119 119 120 120 const handleSearch = async (e) => { … … 168 168 169 169 return ( 170 <div> 171 <h1 className="text-3xl font-bold mb-6" style={{ color: '#7c3aed' }}>Medical Records</h1> 172 173 {error && <ErrorAlert message={error} onClose={() => setError(null)} />} 174 175 {/* Search Form - Only show for non-patients */} 176 {!isPatient && ( 177 <div className="bg-white rounded-lg shadow p-6 mb-6"> 178 <h2 className="text-xl font-bold mb-4">Search Medical Records</h2> 179 <form onSubmit={handleSearch} className="space-y-4"> 180 <div className="flex gap-4"> 181 <div className="flex-1"> 182 <label className="block text-sm font-semibold mb-2">Patient EMBG</label> 183 <input 184 type="text" 185 value={embg} 186 onChange={(e) => setEmbg(e.target.value)} 187 placeholder="e.g., 1402994123456" 188 className="w-full px-4 py-2 border rounded-lg" 189 /> 190 </div> 191 <div className="flex items-end"> 192 <button 193 type="submit" 194 disabled={loading} 195 className="bg-purple-600 text-white px-8 py-2 rounded-full hover:bg-purple-700 disabled:bg-gray-400" 196 > 197 {loading ? 'Searching...' : 'Search'} 198 </button> 199 </div> 200 </div> 201 </form> 170 <div> 171 <h1 className="text-3xl font-bold mb-6" style={{ color: '#7c3aed' }}>Medical Records</h1> 172 173 {error && <ErrorAlert message={error} onClose={() => setError(null)} />} 174 175 {/* Search Form - Only show for non-patients */} 176 {!isPatient && ( 177 <div className="bg-white rounded-lg shadow p-6 mb-6"> 178 <h2 className="text-xl font-bold mb-4">Search Medical Records</h2> 179 <form onSubmit={handleSearch} className="space-y-4"> 180 <div className="flex gap-4"> 181 <div className="flex-1"> 182 <label className="block text-sm font-semibold mb-2">Patient EMBG</label> 183 <input 184 type="text" 185 value={embg} 186 onChange={(e) => setEmbg(e.target.value)} 187 placeholder="e.g., 1402994123456" 188 className="w-full px-4 py-2 border rounded-lg" 189 /> 190 </div> 191 <div className="flex items-end"> 192 <button 193 type="submit" 194 disabled={loading} 195 className="bg-purple-600 text-white px-8 py-2 rounded-full hover:bg-purple-700 disabled:bg-gray-400" 196 > 197 {loading ? 'Searching...' : 'Search'} 198 </button> 199 </div> 202 200 </div> 203 )} 204 205 {/* Loading indicator for patients fetching their records */} 206 {isPatient && loading && ( 207 <div className="bg-blue-50 rounded-lg shadow p-6 mb-6"> 208 <p className="text-sm text-gray-700"> 209 <strong>Loading your medical records...</strong> 210 </p> 201 </form> 202 </div> 203 )} 204 205 {/* Loading indicator for patients fetching their records */} 206 {isPatient && loading && ( 207 <div className="bg-blue-50 rounded-lg shadow p-6 mb-6"> 208 <p className="text-sm text-gray-700"> 209 <strong>Loading your medical records...</strong> 210 </p> 211 </div> 212 )} 213 214 {/* Patient Info Message for Patients */} 215 {isPatient && searched && !loading && ( 216 <div className="bg-blue-50 rounded-lg shadow p-6 mb-6"> 217 <p className="text-sm text-gray-700"> 218 <strong>Viewing your medical records</strong> 219 </p> 220 </div> 221 )} 222 223 {/* Patient Medical Records */} 224 {searched && patient && ( 225 <div className="space-y-6"> 226 {/* Patient Info */} 227 <div className="bg-white rounded-lg shadow p-6"> 228 <div className="flex justify-between items-start mb-4"> 229 <h2 className="text-2xl font-bold">{patient.firstName} {patient.lastName}</h2> 230 {!isPatient && ( 231 <button 232 onClick={() => navigate(`/medical-records/${patient.patientId}`)} 233 className="bg-purple-600 text-white px-4 py-2 rounded hover:bg-purple-700" 234 > 235 Add Medical Data 236 </button> 237 )} 211 238 </div> 212 )} 213 214 {/* Patient Info Message for Patients */} 215 {isPatient && searched && !loading && ( 216 <div className="bg-blue-50 rounded-lg shadow p-6 mb-6"> 217 <p className="text-sm text-gray-700"> 218 <strong>Viewing your medical records</strong> 219 </p> 239 <div className="grid grid-cols-4 gap-4"> 240 <div> 241 <p className="text-sm text-gray-600">EMBG</p> 242 <p className="font-semibold">{patient.embg}</p> 243 </div> 244 <div> 245 <p className="text-sm text-gray-600">Email</p> 246 <p className="font-semibold">{patient.emailAddress}</p> 247 </div> 248 <div> 249 <p className="text-sm text-gray-600">Blood Type</p> 250 <p className="font-semibold">{patient.bloodType || 'N/A'}</p> 251 </div> 252 <div> 253 <p className="text-sm text-gray-600">Date of Birth</p> 254 <p className="font-semibold">{patient.dateOfBirth}</p> 255 </div> 220 256 </div> 221 )} 222 223 {/* Patient Medical Records */} 224 {searched && patient && ( 225 <div className="space-y-6"> 226 {/* Patient Info */} 227 <div className="bg-white rounded-lg shadow p-6"> 228 <div className="flex justify-between items-start mb-4"> 229 <h2 className="text-2xl font-bold">{patient.firstName} {patient.lastName}</h2> 230 {!isPatient && ( 231 <button 232 onClick={() => navigate(`/medical-records/${patient.patientId}`)} 233 className="bg-purple-600 text-white px-4 py-2 rounded hover:bg-purple-700" 234 > 235 Add Medical Data 236 </button> 237 )} 238 </div> 239 <div className="grid grid-cols-4 gap-4"> 240 <div> 241 <p className="text-sm text-gray-600">EMBG</p> 242 <p className="font-semibold">{patient.embg}</p> 243 </div> 244 <div> 245 <p className="text-sm text-gray-600">Email</p> 246 <p className="font-semibold">{patient.emailAddress}</p> 247 </div> 248 <div> 249 <p className="text-sm text-gray-600">Blood Type</p> 250 <p className="font-semibold">{patient.bloodType || 'N/A'}</p> 251 </div> 252 <div> 253 <p className="text-sm text-gray-600">Date of Birth</p> 254 <p className="font-semibold">{patient.dateOfBirth}</p> 255 </div> 256 </div> 257 </div> 258 259 {/* Medical Data Sections */} 260 {medicalData && ( 261 <> 262 {/* Diagnoses */} 263 {medicalData.diagnoses && medicalData.diagnoses.length > 0 && ( 264 <div className="bg-white rounded-lg shadow p-6"> 265 <h3 className="text-xl font-bold mb-4">Diagnoses</h3> 266 <div className="space-y-3"> 267 {medicalData.diagnoses.map((diagnosis) => ( 268 <div key={diagnosis.diagnosisId} className="border-l-4 border-purple-500 pl-4 py-2"> 269 <p className="font-semibold text-lg">{diagnosis.name}</p> 270 {diagnosis.description && ( 271 <p className="text-gray-600 text-sm">{diagnosis.description}</p> 272 )} 273 <p className="text-xs text-gray-500">By: {diagnosis.doctorName}</p> 274 </div> 275 ))} 276 </div> 277 </div> 278 )} 279 280 {/* Symptoms */} 281 {medicalData.symptoms && medicalData.symptoms.length > 0 && ( 282 <div className="bg-white rounded-lg shadow p-6"> 283 <h3 className="text-xl font-bold mb-4">Symptoms</h3> 284 <div className="flex flex-wrap gap-2"> 285 {medicalData.symptoms.map((symptom) => ( 286 <span key={symptom.symptomId} className="bg-yellow-100 text-yellow-800 px-3 py-1 rounded-full text-sm"> 257 </div> 258 259 {/* Medical Data Sections */} 260 {medicalData && ( 261 <> 262 {/* Diagnoses */} 263 {medicalData.diagnoses && medicalData.diagnoses.length > 0 && ( 264 <div className="bg-white rounded-lg shadow p-6"> 265 <h3 className="text-xl font-bold mb-4">Diagnoses</h3> 266 <div className="space-y-3"> 267 {medicalData.diagnoses.map((diagnosis) => ( 268 <div key={diagnosis.diagnosisId} className="border-l-4 border-purple-500 pl-4 py-2"> 269 <p className="font-semibold text-lg">{diagnosis.name}</p> 270 {diagnosis.description && ( 271 <p className="text-gray-600 text-sm">{diagnosis.description}</p> 272 )} 273 <p className="text-xs text-gray-500">By: {diagnosis.doctorName}</p> 274 </div> 275 ))} 276 </div> 277 </div> 278 )} 279 280 {/* Symptoms */} 281 {medicalData.symptoms && medicalData.symptoms.length > 0 && ( 282 <div className="bg-white rounded-lg shadow p-6"> 283 <h3 className="text-xl font-bold mb-4">Symptoms</h3> 284 <div className="flex flex-wrap gap-2"> 285 {medicalData.symptoms.map((symptom) => ( 286 <span key={symptom.symptomId} className="bg-yellow-100 text-yellow-800 px-3 py-1 rounded-full text-sm"> 287 287 {symptom.symptomName} 288 288 </span> 289 ))}290 </div>291 </div>292 )}293 294 {/* Allergies */}295 {medicalData.allergies && medicalData.allergies.length > 0 && (296 <div className="bg-white rounded-lg shadow p-6">297 <h3 className="text-xl font-bold mb-4">Allergies</h3>298 <div className="space-y-3">299 {medicalData.allergies.map((allergy) => (300 <div key={allergy.allergyId} className="border-l-4 border-red-500 pl-4 py-2">301 <p className="font-semibold">{allergy.allergyName}</p>302 <p className="text-sm">289 ))} 290 </div> 291 </div> 292 )} 293 294 {/* Allergies */} 295 {medicalData.allergies && medicalData.allergies.length > 0 && ( 296 <div className="bg-white rounded-lg shadow p-6"> 297 <h3 className="text-xl font-bold mb-4">Allergies</h3> 298 <div className="space-y-3"> 299 {medicalData.allergies.map((allergy) => ( 300 <div key={allergy.allergyId} className="border-l-4 border-red-500 pl-4 py-2"> 301 <p className="font-semibold">{allergy.allergyName}</p> 302 <p className="text-sm"> 303 303 <span className={`px-2 py-1 rounded text-white text-xs ${ 304 allergy.severity === 'CRITICAL' ? 'bg-red-600' :305 allergy.severity === 'HIGH' ? 'bg-red-500' :306 allergy.severity === 'MEDIUM' ? 'bg-yellow-500' :307 'bg-green-500'304 allergy.severity === 'CRITICAL' ? 'bg-red-600' : 305 allergy.severity === 'HIGH' ? 'bg-red-500' : 306 allergy.severity === 'MEDIUM' ? 'bg-yellow-500' : 307 'bg-green-500' 308 308 }`}> 309 309 {allergy.severity} Severity 310 310 </span> 311 </p>312 {allergy.reaction && (313 <p className="text-gray-600 text-sm">Reaction: {allergy.reaction}</p>314 )}315 </div>316 ))}317 </div>318 </div>319 )}320 321 {/* Medical Reports */}322 {medicalData.reports && medicalData.reports.length > 0 && (323 <div className="bg-white rounded-lg shadow p-6">324 <h3 className="text-xl font-bold mb-4">Medical Reports</h3>325 <div className="space-y-3">326 {medicalData.reports.map((report) => (327 <div key={report.reportId} className="border-l-4 border-green-500 pl-4 py-2">328 <p className="font-semibold">Report from {report.doctorName}</p>329 <p className="text-gray-600 text-sm">{report.description}</p>330 <p className="text-xs text-gray-500">Date: {report.reportDate}</p>331 </div>332 ))}333 </div>334 </div>335 )}336 337 {/* Lab Test Results */}338 {labResults && labResults.length > 0 && (339 <div className="bg-white rounded-lg shadow p-6">340 <h3 className="text-xl font-bold mb-4">Lab Test Results</h3>341 <div className="space-y-3">342 {labResults.map((result) => (343 <div key={result.labResultId} className="border-l-4 border-purple-500 pl-4 py-2">344 <p className="font-semibold">{result.testName}</p>345 <p className="text-gray-600 text-sm">{result.result}</p>346 {result.notes && (347 <p className="text-gray-600 text-sm">Notes: {result.notes}</p>348 )}349 <p className="text-xs text-gray-500">Date: {result.resultDate}</p>350 {result.technicianName && (351 <p className="text-xs text-gray-500">Technician: {result.technicianName}</p>352 )}353 </div>354 ))}355 </div>356 </div>357 )}358 359 {/* Procedure Results */}360 {procedureResults && procedureResults.length > 0 && (361 <div className="bg-white rounded-lg shadow p-6">362 <h3 className="text-xl font-bold mb-4">Procedure Results</h3>363 <div className="space-y-3">364 {procedureResults.map((result) => (365 <div key={result.procedureResultId} className="border-l-4 border-orange-500 pl-4 py-2">366 <p className="font-semibold">{result.procedureName}</p>367 <p className="text-gray-600 text-sm">{result.result}</p>368 {result.notes && (369 <p className="text-gray-600 text-sm">Notes: {result.notes}</p>370 )}371 <p className="text-xs text-gray-500">Date: {result.resultDate}</p>372 {result.doctorName && (373 <p className="text-xs text-gray-500">Doctor: {result.doctorName}</p>374 )}375 </div>376 ))}377 </div>378 </div>379 )}380 381 {/* No data message */}382 {(!medicalData.diagnoses || medicalData.diagnoses.length === 0) &&383 (!medicalData.symptoms || medicalData.symptoms.length === 0) &&384 (!medicalData.allergies || medicalData.allergies.length === 0) &&385 (!medicalData.reports || medicalData.reports.length === 0) &&386 (!labResults || labResults.length === 0) &&387 (!procedureResults || procedureResults.length === 0) && (388 <div className="bg-blue-50 rounded-lg p-6 text-center">389 <p className="text-gray-600">No medical records found for this patient</p>390 </div>391 )}392 </>393 )}394 </div>395 )}396 397 {/* No search performed */}398 {!searched && !isPatient && (399 <div className="bg-gray-50 rounded-lg p-12 text-center">400 <p className="text-gray-600 text-lg">Enter a patient EMBG to view their medical records</p>401 </div>402 )}403 404 {/* Loading message for patients */}405 {isPatient && loading && (406 <div className="bg-gray-50 rounded-lg p-12 text-center">407 <p className="text-gray-600 text-lg">Loading your medical records...</p>408 </div>409 )}410 </div>311 </p> 312 {allergy.reaction && ( 313 <p className="text-gray-600 text-sm">Reaction: {allergy.reaction}</p> 314 )} 315 </div> 316 ))} 317 </div> 318 </div> 319 )} 320 321 {/* Medical Reports */} 322 {medicalData.reports && medicalData.reports.length > 0 && ( 323 <div className="bg-white rounded-lg shadow p-6"> 324 <h3 className="text-xl font-bold mb-4">Medical Reports</h3> 325 <div className="space-y-3"> 326 {medicalData.reports.map((report) => ( 327 <div key={report.reportId} className="border-l-4 border-green-500 pl-4 py-2"> 328 <p className="font-semibold">Report from {report.doctorName}</p> 329 <p className="text-gray-600 text-sm">{report.description}</p> 330 <p className="text-xs text-gray-500">Date: {report.reportDate}</p> 331 </div> 332 ))} 333 </div> 334 </div> 335 )} 336 337 {/* Lab Test Results */} 338 {labResults && labResults.length > 0 && ( 339 <div className="bg-white rounded-lg shadow p-6"> 340 <h3 className="text-xl font-bold mb-4">Lab Test Results</h3> 341 <div className="space-y-3"> 342 {labResults.map((result) => ( 343 <div key={result.labResultId} className="border-l-4 border-purple-500 pl-4 py-2"> 344 <p className="font-semibold">{result.testName}</p> 345 <p className="text-gray-600 text-sm">{result.result}</p> 346 {result.notes && ( 347 <p className="text-gray-600 text-sm">Notes: {result.notes}</p> 348 )} 349 <p className="text-xs text-gray-500">Date: {result.resultDate}</p> 350 {result.technicianName && ( 351 <p className="text-xs text-gray-500">Technician: {result.technicianName}</p> 352 )} 353 </div> 354 ))} 355 </div> 356 </div> 357 )} 358 359 {/* Procedure Results */} 360 {procedureResults && procedureResults.length > 0 && ( 361 <div className="bg-white rounded-lg shadow p-6"> 362 <h3 className="text-xl font-bold mb-4">Procedure Results</h3> 363 <div className="space-y-3"> 364 {procedureResults.map((result) => ( 365 <div key={result.procedureResultId} className="border-l-4 border-orange-500 pl-4 py-2"> 366 <p className="font-semibold">{result.procedureName}</p> 367 <p className="text-gray-600 text-sm">{result.result}</p> 368 {result.notes && ( 369 <p className="text-gray-600 text-sm">Notes: {result.notes}</p> 370 )} 371 <p className="text-xs text-gray-500">Date: {result.resultDate}</p> 372 {result.doctorName && ( 373 <p className="text-xs text-gray-500">Doctor: {result.doctorName}</p> 374 )} 375 </div> 376 ))} 377 </div> 378 </div> 379 )} 380 381 {/* No data message */} 382 {(!medicalData.diagnoses || medicalData.diagnoses.length === 0) && 383 (!medicalData.symptoms || medicalData.symptoms.length === 0) && 384 (!medicalData.allergies || medicalData.allergies.length === 0) && 385 (!medicalData.reports || medicalData.reports.length === 0) && 386 (!labResults || labResults.length === 0) && 387 (!procedureResults || procedureResults.length === 0) && ( 388 <div className="bg-blue-50 rounded-lg p-6 text-center"> 389 <p className="text-gray-600">No medical records found for this patient</p> 390 </div> 391 )} 392 </> 393 )} 394 </div> 395 )} 396 397 {/* No search performed */} 398 {!searched && !isPatient && ( 399 <div className="bg-gray-50 rounded-lg p-12 text-center"> 400 <p className="text-gray-600 text-lg">Enter a patient EMBG to view their medical records</p> 401 </div> 402 )} 403 404 {/* Loading message for patients */} 405 {isPatient && loading && ( 406 <div className="bg-gray-50 rounded-lg p-12 text-center"> 407 <p className="text-gray-600 text-lg">Loading your medical records...</p> 408 </div> 409 )} 410 </div> 411 411 ); 412 412 }
Note:
See TracChangeset
for help on using the changeset viewer.
