SmartHeal commited on
Commit
ea28d19
·
verified ·
1 Parent(s): ed01628

Update src/patient_history.py

Browse files
Files changed (1) hide show
  1. src/patient_history.py +110 -102
src/patient_history.py CHANGED
@@ -349,117 +349,125 @@ class ReportGenerator:
349
  return f"<ul>{lis}</ul>"
350
 
351
  def generate_analysis_report(self, patient_data: Dict, analysis_data: Dict, image_url: str = None) -> str:
352
- """
353
- Generate comprehensive printable HTML report for a single analysis.
354
- """
355
- risk_level = (analysis_data or {}).get("risk_level", "Unknown")
356
- risk_class = f"risk-{str(risk_level).lower().replace(' ', '-')}"
357
- summary = (analysis_data or {}).get("summary", "No analysis summary available.")
358
- recs = self._format_recommendations((analysis_data or {}).get("recommendations", ""))
359
-
360
- return f"""
361
- <!DOCTYPE html>
362
- <html lang="en">
363
- <head>
364
- <meta charset="UTF-8">
365
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
366
- <title>SmartHeal AI - Wound Analysis Report</title>
367
- <style>
368
- body {{
369
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
370
- line-height: 1.6; margin: 0; padding: 20px; background-color: #f8f9fa;
371
- }}
372
- .report-container {{ max-width: 920px; margin: 0 auto; background: white; border-radius: 10px;
373
- box-shadow: 0 4px 20px rgba(0,0,0,0.1); overflow: hidden; }}
374
- .header {{ background: linear-gradient(135deg, #3182ce 0%, #2c5aa0 100%); color: white; padding: 30px; text-align: center; }}
375
- .header h1 {{ margin: 0; font-size: 28px; font-weight: 600; }}
376
- .header p {{ margin: 10px 0 0 0; opacity: 0.9; font-size: 16px; }}
377
- .content {{ padding: 30px; }}
378
- .section {{ margin-bottom: 30px; border-left: 4px solid #3182ce; padding-left: 20px; }}
379
- .section h2 {{ color: #2c5aa0; margin-top: 0; font-size: 20px; font-weight: 600; }}
380
- .grid2 {{ display:grid; grid-template-columns:1fr 1fr; gap:20px; }}
381
- .card {{ background:#f8f9fa; padding:15px; border-radius:8px; border:1px solid #e9ecef; }}
382
- .card h3 {{ margin:0 0 10px 0; color:#495057; font-size:13px; font-weight:700; text-transform:uppercase; }}
383
- .card p {{ margin:0; font-weight:500; color:#212529; }}
384
- .risk-indicator {{ display:inline-block; padding:8px 16px; border-radius:20px; font-weight:600; text-transform:uppercase; font-size:12px; letter-spacing:.5px; }}
385
- .risk-low {{ background:#d4edda; color:#155724; }}
386
- .risk-moderate {{ background:#fff3cd; color:#856404; }}
387
- .risk-high {{ background:#f8d7da; color:#721c24; }}
388
- .recommendations {{ background:#e7f3ff; border:1px solid #b3d9ff; border-radius:8px; padding:20px; margin-top:15px; }}
389
- .image-wrap {{ text-align:center; margin:20px 0; }}
390
- .wound-image {{ max-width:100%; height:auto; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,.15); }}
391
- .footer {{ background:#f8f9fa; padding:20px 30px; text-align:center; color:#6c757d; border-top:1px solid #e9ecef; }}
392
- @media print {{ body {{ background:white; }} .report-container {{ box-shadow:none; }} }}
393
- </style>
394
- </head>
395
- <body>
396
- <div class="report-container">
397
- <div class="header">
398
- <h1>🩺 SmartHeal AI Wound Analysis Report</h1>
399
- <p>Advanced AI-Powered Clinical Assessment</p>
400
  </div>
401
-
402
- <div class="content">
403
- <div class="section">
404
- <h2>Patient Information</h2>
405
- <div class="grid2">
406
- <div class="card"><h3>Patient Name</h3><p>{html.escape(str(patient_data.get('patient_name','N/A')))}</p></div>
407
- <div class="card"><h3>Age</h3><p>{html.escape(str(patient_data.get('patient_age','N/A')))} years</p></div>
408
- <div class="card"><h3>Gender</h3><p>{html.escape(str(patient_data.get('patient_gender','N/A')))}</p></div>
409
- <div class="card"><h3>Assessment Date</h3><p>{datetime.now().strftime('%B %d, %Y at %I:%M %p')}</p></div>
410
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
411
  </div>
412
-
413
- <div class="section">
414
- <h2>Wound Assessment</h2>
415
- <div class="grid2">
416
- <div class="card"><h3>Location</h3><p>{html.escape(str(patient_data.get('wound_location','N/A')))}</p></div>
417
- <div class="card"><h3>Duration</h3><p>{html.escape(str(patient_data.get('wound_duration','N/A')))}</p></div>
418
- <div class="card"><h3>Pain Level</h3><p>{html.escape(str(patient_data.get('pain_level','N/A')))} / 10</p></div>
419
- <div class="card"><h3>Risk Assessment</h3>
420
- <p><span class="risk-indicator risk-{html.escape(risk_class)}">{html.escape(str(risk_level))} Risk</span></p>
421
  </div>
422
  </div>
423
- </div>
424
-
425
- {f"""
426
- <div class="section">
427
- <h2>Wound Image</h2>
428
- <div class="image-wrap">
429
- <img src="{html.escape(image_url)}" alt="Wound Image" class="wound-image" />
 
 
 
 
430
  </div>
431
- </div>""" if image_url else ""}
432
-
433
- <div class="section">
434
- <h2>AI Analysis Summary</h2>
435
- <p>{html.escape(str(summary))}</p>
436
- <div class="recommendations">
437
- <h3>🎯 Clinical Recommendations</h3>
438
- {recs}
 
 
439
  </div>
440
- </div>
441
-
442
- <div class="section">
443
- <h2>Medical History</h2>
444
- <div class="grid2">
445
- <div class="card"><h3>Medical History</h3><p>{html.escape(str(patient_data.get('medical_history','None reported')))}</p></div>
446
- <div class="card"><h3>Current Medications</h3><p>{html.escape(str(patient_data.get('medications','None reported')))}</p></div>
447
- <div class="card"><h3>Known Allergies</h3><p>{html.escape(str(patient_data.get('allergies','None reported')))}</p></div>
448
- <div class="card"><h3>Additional Notes</h3><p>{html.escape(str(patient_data.get('additional_notes','None')))}</p></div>
449
  </div>
450
  </div>
 
 
 
 
 
 
451
  </div>
452
-
453
- <div class="footer">
454
- <p><strong>SmartHeal AI</strong> — Advanced Wound Care Analysis & Clinical Support System</p>
455
- <p>Generated on {datetime.now().strftime('%B %d, %Y at %I:%M %p')} | For professional medical use only</p>
456
- <p>⚠️ This AI analysis is for clinical support only. Always consult qualified professionals.</p>
457
- </div>
458
- </div>
459
- </body>
460
- </html>
461
- """
462
-
463
  def generate_patient_history_report(self, patient_history: List[Dict]) -> str:
464
  """
465
  Large, printable HTML summarizing multiple visits for a patient.
 
349
  return f"<ul>{lis}</ul>"
350
 
351
  def generate_analysis_report(self, patient_data: Dict, analysis_data: Dict, image_url: str = None) -> str:
352
+ """
353
+ Generate comprehensive printable HTML report for a single analysis.
354
+ """
355
+ risk_level = (analysis_data or {}).get("risk_level", "Unknown")
356
+ risk_class = f"risk-{str(risk_level).lower().replace(' ', '-')}"
357
+ summary = (analysis_data or {}).get("summary", "No analysis summary available.")
358
+ recs = self._format_recommendations((analysis_data or {}).get("recommendations", ""))
359
+
360
+ # Build optional image section first to avoid nested f-strings
361
+ image_section = (
362
+ f"""
363
+ <div class="section">
364
+ <h2>Wound Image</h2>
365
+ <div class="image-wrap">
366
+ <img src="{html.escape(image_url)}" alt="Wound Image" class="wound-image" />
367
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  </div>
369
+ """ if image_url else ""
370
+ )
371
+
372
+ return f"""
373
+ <!DOCTYPE html>
374
+ <html lang="en">
375
+ <head>
376
+ <meta charset="UTF-8">
377
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
378
+ <title>SmartHeal AI - Wound Analysis Report</title>
379
+ <style>
380
+ body {{
381
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
382
+ line-height: 1.6; margin: 0; padding: 20px; background-color: #f8f9fa;
383
+ }}
384
+ .report-container {{ max-width: 920px; margin: 0 auto; background: white; border-radius: 10px;
385
+ box-shadow: 0 4px 20px rgba(0,0,0,0.1); overflow: hidden; }}
386
+ .header {{ background: linear-gradient(135deg, #3182ce 0%, #2c5aa0 100%); color: white; padding: 30px; text-align: center; }}
387
+ .header h1 {{ margin: 0; font-size: 28px; font-weight: 600; }}
388
+ .header p {{ margin: 10px 0 0 0; opacity: 0.9; font-size: 16px; }}
389
+ .content {{ padding: 30px; }}
390
+ .section {{ margin-bottom: 30px; border-left: 4px solid #3182ce; padding-left: 20px; }}
391
+ .section h2 {{ color: #2c5aa0; margin-top: 0; font-size: 20px; font-weight: 600; }}
392
+ .grid2 {{ display:grid; grid-template-columns:1fr 1fr; gap:20px; }}
393
+ .card {{ background:#f8f9fa; padding:15px; border-radius:8px; border:1px solid #e9ecef; }}
394
+ .card h3 {{ margin:0 0 10px 0; color:#495057; font-size:13px; font-weight:700; text-transform:uppercase; }}
395
+ .card p {{ margin:0; font-weight:500; color:#212529; }}
396
+ .risk-indicator {{ display:inline-block; padding:8px 16px; border-radius:20px; font-weight:600; text-transform:uppercase; font-size:12px; letter-spacing:.5px; }}
397
+ .risk-low {{ background:#d4edda; color:#155724; }}
398
+ .risk-moderate {{ background:#fff3cd; color:#856404; }}
399
+ .risk-high {{ background:#f8d7da; color:#721c24; }}
400
+ .recommendations {{ background:#e7f3ff; border:1px solid #b3d9ff; border-radius:8px; padding:20px; margin-top:15px; }}
401
+ .image-wrap {{ text-align:center; margin:20px 0; }}
402
+ .wound-image {{ max-width:100%; height:auto; border-radius:8px; box-shadow:0 4px 12px rgba(0,0,0,.15); }}
403
+ .footer {{ background:#f8f9fa; padding:20px 30px; text-align:center; color:#6c757d; border-top:1px solid #e9ecef; }}
404
+ @media print {{ body {{ background:white; }} .report-container {{ box-shadow:none; }} }}
405
+ </style>
406
+ </head>
407
+ <body>
408
+ <div class="report-container">
409
+ <div class="header">
410
+ <h1>🩺 SmartHeal AI Wound Analysis Report</h1>
411
+ <p>Advanced AI-Powered Clinical Assessment</p>
412
  </div>
413
+
414
+ <div class="content">
415
+ <div class="section">
416
+ <h2>Patient Information</h2>
417
+ <div class="grid2">
418
+ <div class="card"><h3>Patient Name</h3><p>{html.escape(str(patient_data.get('patient_name','N/A')))}</p></div>
419
+ <div class="card"><h3>Age</h3><p>{html.escape(str(patient_data.get('patient_age','N/A')))} years</p></div>
420
+ <div class="card"><h3>Gender</h3><p>{html.escape(str(patient_data.get('patient_gender','N/A')))}</p></div>
421
+ <div class="card"><h3>Assessment Date</h3><p>{datetime.now().strftime('%B %d, %Y at %I:%M %p')}</p></div>
422
  </div>
423
  </div>
424
+
425
+ <div class="section">
426
+ <h2>Wound Assessment</h2>
427
+ <div class="grid2">
428
+ <div class="card"><h3>Location</h3><p>{html.escape(str(patient_data.get('wound_location','N/A')))}</p></div>
429
+ <div class="card"><h3>Duration</h3><p>{html.escape(str(patient_data.get('wound_duration','N/A')))}</p></div>
430
+ <div class="card"><h3>Pain Level</h3><p>{html.escape(str(patient_data.get('pain_level','N/A')))} / 10</p></div>
431
+ <div class="card"><h3>Risk Assessment</h3>
432
+ <p><span class="risk-indicator risk-{html.escape(risk_class)}">{html.escape(str(risk_level))} Risk</span></p>
433
+ </div>
434
+ </div>
435
  </div>
436
+
437
+ {image_section}
438
+
439
+ <div class="section">
440
+ <h2>AI Analysis Summary</h2>
441
+ <p>{html.escape(str(summary))}</p>
442
+ <div class="recommendations">
443
+ <h3>🎯 Clinical Recommendations</h3>
444
+ {recs}
445
+ </div>
446
  </div>
447
+
448
+ <div class="section">
449
+ <h2>Medical History</h2>
450
+ <div class="grid2">
451
+ <div class="card"><h3>Medical History</h3><p>{html.escape(str(patient_data.get('medical_history','None reported')))}</p></div>
452
+ <div class="card"><h3>Current Medications</h3><p>{html.escape(str(patient_data.get('medications','None reported')))}</p></div>
453
+ <div class="card"><h3>Known Allergies</h3><p>{html.escape(str(patient_data.get('allergies','None reported')))}</p></div>
454
+ <div class="card"><h3>Additional Notes</h3><p>{html.escape(str(patient_data.get('additional_notes','None')))}</p></div>
455
+ </div>
456
  </div>
457
  </div>
458
+
459
+ <div class="footer">
460
+ <p><strong>SmartHeal AI</strong> — Advanced Wound Care Analysis & Clinical Support System</p>
461
+ <p>Generated on {datetime.now().strftime('%B %d, %Y at %I:%M %p')} | For professional medical use only</p>
462
+ <p>⚠️ This AI analysis is for clinical support only. Always consult qualified professionals.</p>
463
+ </div>
464
  </div>
465
+ </body>
466
+ </html>
467
+ """
468
+
469
+
470
+
 
 
 
 
 
471
  def generate_patient_history_report(self, patient_history: List[Dict]) -> str:
472
  """
473
  Large, printable HTML summarizing multiple visits for a patient.