Skip to content

Commit df0fd92

Browse files
committed
feat: Refactor ReportDetailPage to use modular components for AI analysis and original report, improving code organization and readability
1 parent 3294a69 commit df0fd92

File tree

4 files changed

+154
-42
lines changed

4 files changed

+154
-42
lines changed

frontend/src/pages/Reports/ReportDetailPage.tsx

Lines changed: 5 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,17 @@ import { useHistory, useParams } from 'react-router-dom';
44
import './ReportDetailPage.scss';
55
import { useQuery } from '@tanstack/react-query';
66
import axios from 'axios';
7-
import { MedicalReport, LabValue } from '../../common/models/medicalReport';
7+
import { MedicalReport } from '../../common/models/medicalReport';
88
import { useTranslation } from 'react-i18next';
99
import { getAuthConfig } from 'common/api/reportService';
1010

1111
// Import components
1212
import ReportHeader from './components/ReportHeader';
1313
import ReportTabs from './components/ReportTabs';
14-
import EmergencyAlert from './components/EmergencyAlert';
15-
import FlaggedValuesSection from './components/FlaggedValuesSection';
16-
import NormalValuesSection from './components/NormalValuesSection';
17-
import OriginalReport from './components/OriginalReport';
14+
import OriginalReportTab from './components/OriginalReportTab';
1815
import InfoCard from './components/InfoCard';
1916
import ActionButtons from './components/ActionButtons';
17+
import AiAnalysisTab from './components/AiAnalysisTab';
2018

2119
const API_URL = import.meta.env.VITE_BASE_URL_API || '';
2220

@@ -46,14 +44,8 @@ const ReportDetailPage: React.FC = () => {
4644
});
4745

4846
// State to track expanded sections
49-
const [flaggedValuesExpanded, setFlaggedValuesExpanded] = useState(true);
50-
const [normalValuesExpanded, setNormalValuesExpanded] = useState(true);
5147
const [activeTab, setActiveTab] = useState<'ai' | 'original'>('ai');
5248

53-
// Toggle expanded state of sections
54-
const toggleFlaggedValues = () => setFlaggedValuesExpanded(!flaggedValuesExpanded);
55-
const toggleNormalValues = () => setNormalValuesExpanded(!normalValuesExpanded);
56-
5749
// Handle loading and error states
5850
if (isLoading) {
5951
return <IonPage></IonPage>;
@@ -83,15 +75,6 @@ const ReportDetailPage: React.FC = () => {
8375

8476
const reportData = data;
8577

86-
// Process lab values data
87-
const hasEmergency = reportData.labValues.some((value) => value.isCritical);
88-
const flaggedValues: LabValue[] = reportData.labValues.filter(
89-
(value) => value.status !== 'normal',
90-
);
91-
const normalValues: LabValue[] = reportData.labValues.filter(
92-
(value) => value.status === 'normal',
93-
);
94-
9578
// Handle tab selection
9679
const handleTabChange = (tab: 'ai' | 'original') => {
9780
setActiveTab(tab);
@@ -122,27 +105,10 @@ const ReportDetailPage: React.FC = () => {
122105

123106
{/* Content based on active tab */}
124107
{activeTab === 'ai' ? (
125-
<>
126-
{/* Emergency alert if needed */}
127-
{hasEmergency && <EmergencyAlert />}
128-
129-
{/* Flagged values section */}
130-
<FlaggedValuesSection
131-
flaggedValues={flaggedValues}
132-
isExpanded={flaggedValuesExpanded}
133-
onToggle={toggleFlaggedValues}
134-
/>
135-
136-
{/* Normal values section */}
137-
<NormalValuesSection
138-
normalValues={normalValues}
139-
isExpanded={normalValuesExpanded}
140-
onToggle={toggleNormalValues}
141-
/>
142-
</>
108+
<AiAnalysisTab reportData={reportData} />
143109
) : (
144110
/* Original Report Tab Content */
145-
<OriginalReport reportData={reportData} />
111+
<OriginalReportTab reportData={reportData} />
146112
)}
147113

148114
{/* Doctor information note */}
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import React from 'react';
2+
import { MedicalReport, LabValue } from '../../../common/models/medicalReport';
3+
import EmergencyAlert from './EmergencyAlert';
4+
import FlaggedValuesSection from './FlaggedValuesSection';
5+
import NormalValuesSection from './NormalValuesSection';
6+
7+
interface AiAnalysisTabProps {
8+
reportData: MedicalReport;
9+
isEmergencyAlertVisible?: boolean;
10+
}
11+
12+
const AiAnalysisTab: React.FC<AiAnalysisTabProps> = ({
13+
reportData,
14+
isEmergencyAlertVisible = true,
15+
}) => {
16+
// State to track expanded sections
17+
const [flaggedValuesExpanded, setFlaggedValuesExpanded] = React.useState(true);
18+
const [normalValuesExpanded, setNormalValuesExpanded] = React.useState(true);
19+
20+
// Toggle expanded state of sections
21+
const toggleFlaggedValues = () => setFlaggedValuesExpanded(!flaggedValuesExpanded);
22+
const toggleNormalValues = () => setNormalValuesExpanded(!normalValuesExpanded);
23+
24+
// Process lab values data
25+
const hasEmergency = reportData.labValues.some((value) => value.isCritical);
26+
const flaggedValues: LabValue[] = reportData.labValues.filter(
27+
(value) => value.status !== 'normal',
28+
);
29+
const normalValues: LabValue[] = reportData.labValues.filter(
30+
(value) => value.status === 'normal',
31+
);
32+
33+
return (
34+
<div className="ai-analysis-tab">
35+
{/* Emergency alert if needed */}
36+
{isEmergencyAlertVisible && hasEmergency && <EmergencyAlert />}
37+
38+
{/* Flagged values section */}
39+
<FlaggedValuesSection
40+
flaggedValues={flaggedValues}
41+
isExpanded={flaggedValuesExpanded}
42+
onToggle={toggleFlaggedValues}
43+
/>
44+
45+
{/* Normal values section */}
46+
<NormalValuesSection
47+
normalValues={normalValues}
48+
isExpanded={normalValuesExpanded}
49+
onToggle={toggleNormalValues}
50+
/>
51+
</div>
52+
);
53+
};
54+
55+
export default AiAnalysisTab;

frontend/src/pages/Reports/components/OriginalReport.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import { format } from 'date-fns';
33
import Icon from '../../../common/components/Icon/Icon';
44
import { MedicalReport } from '../../../common/models/medicalReport';
55

6-
interface OriginalReportProps {
6+
interface OriginalReportTabProps {
77
reportData: MedicalReport;
88
}
99

10-
const OriginalReport: React.FC<OriginalReportProps> = ({ reportData }) => {
10+
const OriginalReportTab: React.FC<OriginalReportTabProps> = ({ reportData }) => {
1111
// Function to format file size in KB or MB
1212
const formatFileSize = (bytes: number): string => {
1313
if (bytes < 1024) return bytes + ' B';
@@ -88,4 +88,4 @@ const OriginalReport: React.FC<OriginalReportProps> = ({ reportData }) => {
8888
);
8989
};
9090

91-
export default OriginalReport;
91+
export default OriginalReportTab;
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import React from 'react';
2+
import { format } from 'date-fns';
3+
import Icon from '../../../common/components/Icon/Icon';
4+
import { MedicalReport } from '../../../common/models/medicalReport';
5+
6+
interface OriginalReportTabProps {
7+
reportData: MedicalReport;
8+
}
9+
10+
const OriginalReportTab: React.FC<OriginalReportTabProps> = ({ reportData }) => {
11+
// Function to format file size in KB or MB
12+
const formatFileSize = (bytes: number): string => {
13+
if (bytes < 1024) return bytes + ' B';
14+
else if (bytes < 1048576) return Math.round(bytes / 1024) + ' KB';
15+
else return (bytes / 1048576).toFixed(1) + ' MB';
16+
};
17+
18+
// Get filename from originalFilename or fall back to file path
19+
const filename =
20+
reportData.originalFilename || reportData.filePath.split('/').pop() || 'Unknown file';
21+
22+
// Format file size if available
23+
const fileSize = reportData.fileSize ? formatFileSize(reportData.fileSize) : 'Unknown size';
24+
25+
return (
26+
<div className="report-detail-page__original-report">
27+
{/* Test results table */}
28+
<div className="report-detail-page__results-table">
29+
<div className="report-detail-page__results-header">
30+
<div className="report-detail-page__results-cell report-detail-page__results-cell--test">
31+
Test
32+
</div>
33+
<div className="report-detail-page__results-cell report-detail-page__results-cell--value">
34+
Results
35+
</div>
36+
<div className="report-detail-page__results-cell report-detail-page__results-cell--ref">
37+
Ref.
38+
</div>
39+
</div>
40+
41+
{/* Test Results Rows */}
42+
{reportData.labValues.map((labValue, index) => (
43+
<div
44+
key={index}
45+
className={`report-detail-page__results-row ${
46+
labValue.status !== 'normal' ? 'report-detail-page__results-row--flagged' : ''
47+
}`}
48+
>
49+
<div className="report-detail-page__results-cell report-detail-page__results-cell--test">
50+
{labValue.name}
51+
</div>
52+
<div className="report-detail-page__results-cell report-detail-page__results-cell--value">
53+
{labValue.value} {labValue.unit}
54+
</div>
55+
<div className="report-detail-page__results-cell report-detail-page__results-cell--ref">
56+
{labValue.normalRange}
57+
</div>
58+
</div>
59+
))}
60+
</div>
61+
62+
{/* Medical Comments Section */}
63+
<div className="report-detail-page__comments-section">
64+
<h4 className="report-detail-page__comments-title">Medical Comments:</h4>
65+
<div className="report-detail-page__comments-text">{reportData.summary}</div>
66+
</div>
67+
68+
{/* Uploaded File Section */}
69+
<div className="report-detail-page__uploaded-file">
70+
<h4 className="report-detail-page__uploaded-file-title">Uploaded file</h4>
71+
<div className="report-detail-page__file-container">
72+
<div className="report-detail-page__file-icon">
73+
<Icon icon="filePdf" />
74+
</div>
75+
<div className="report-detail-page__file-details">
76+
<div className="report-detail-page__file-name">{filename}</div>
77+
<div className="report-detail-page__file-info">
78+
<span className="report-detail-page__file-size">{fileSize}</span>
79+
<span className="report-detail-page__file-separator"></span>
80+
<span className="report-detail-page__file-date">
81+
Uploaded ({format(new Date(reportData.createdAt), 'MM/dd/yyyy')})
82+
</span>
83+
</div>
84+
</div>
85+
</div>
86+
</div>
87+
</div>
88+
);
89+
};
90+
91+
export default OriginalReportTab;

0 commit comments

Comments
 (0)