11import { IonPage , IonContent } from '@ionic/react' ;
22import { useState } from 'react' ;
33import { useHistory , useParams } from 'react-router-dom' ;
4- import Icon from '../../common/components/Icon/Icon' ;
54import './ReportDetailPage.scss' ;
65import { useQuery } from '@tanstack/react-query' ;
76import axios from 'axios' ;
87import { MedicalReport , LabValue } from '../../common/models/medicalReport' ;
98import { useTranslation } from 'react-i18next' ;
109import { getAuthConfig } from 'common/api/reportService' ;
11- import { format } from 'date-fns' ;
10+
11+ // Import components
12+ import ReportHeader from './components/ReportHeader' ;
13+ 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' ;
18+ import InfoCard from './components/InfoCard' ;
19+ import ActionButtons from './components/ActionButtons' ;
1220
1321const API_URL = import . meta. env . VITE_BASE_URL_API || '' ;
1422
@@ -75,12 +83,11 @@ const ReportDetailPage: React.FC = () => {
7583
7684 const reportData = data ;
7785
86+ // Process lab values data
7887 const hasEmergency = reportData . labValues . some ( ( value ) => value . isCritical ) ;
79-
8088 const flaggedValues : LabValue [ ] = reportData . labValues . filter (
8189 ( value ) => value . status !== 'normal' ,
8290 ) ;
83-
8491 const normalValues : LabValue [ ] = reportData . labValues . filter (
8592 ( value ) => value . status === 'normal' ,
8693 ) ;
@@ -107,298 +114,42 @@ const ReportDetailPage: React.FC = () => {
107114 return (
108115 < IonPage className = "report-detail-page" >
109116 < IonContent fullscreen >
110- { /* Header section */ }
111- < div className = "report-detail-page__header" >
112- < div className = "report-detail-page__title-container" >
113- < h1 className = "report-detail-page__title" > Results Analysis</ h1 >
114- < button className = "report-detail-page__close-button" onClick = { handleClose } >
115- < svg
116- width = "24"
117- height = "24"
118- viewBox = "0 0 24 24"
119- fill = "none"
120- xmlns = "http://www.w3.org/2000/svg"
121- >
122- < path
123- d = "M18 6L6 18"
124- stroke = "#435FF0"
125- strokeWidth = "2.5"
126- strokeLinecap = "round"
127- strokeLinejoin = "round"
128- />
129- < path
130- d = "M6 6L18 18"
131- stroke = "#435FF0"
132- strokeWidth = "2.5"
133- strokeLinecap = "round"
134- strokeLinejoin = "round"
135- />
136- </ svg >
137- </ button >
138- </ div >
139-
140- { /* Category & Title */ }
141- < div className = "report-detail-page__category-wrapper" >
142- < span className = "report-detail-page__category" >
143- { t ( `list.${ reportData . category } Category` , { ns : 'report' } ) }
144- </ span >
145- < button className = "report-detail-page__bookmark-button" >
146- < Icon icon = "bookmark" iconStyle = "regular" />
147- </ button >
148- </ div >
149- < h2 className = "report-detail-page__subtitle" > { reportData . title } </ h2 >
150- </ div >
117+ { /* Header component */ }
118+ < ReportHeader reportData = { reportData } onClose = { handleClose } />
151119
152120 { /* Tab selector for AI Insights vs Original Report */ }
153- < div className = "report-detail-page__tabs" >
154- < div
155- className = { `report-detail-page__tab ${
156- activeTab === 'ai' ? 'report-detail-page__tab--active' : ''
157- } `}
158- onClick = { ( ) => handleTabChange ( 'ai' ) }
159- >
160- < svg
161- className = "report-detail-page__tab-icon-chevron"
162- width = "16"
163- height = "16"
164- viewBox = "0 0 24 24"
165- fill = "none"
166- xmlns = "http://www.w3.org/2000/svg"
167- >
168- < path
169- d = "M18.5 14.75L12 8.25L5.5 14.75"
170- stroke = "#435FF0"
171- strokeWidth = "2"
172- strokeLinecap = "round"
173- strokeLinejoin = "round"
174- />
175- </ svg >
176- AI Insights
177- </ div >
178- < div
179- className = { `report-detail-page__tab ${
180- activeTab === 'original' ? 'report-detail-page__tab--active' : ''
181- } `}
182- onClick = { ( ) => handleTabChange ( 'original' ) }
183- >
184- Original Report
185- </ div >
186- </ div >
121+ < ReportTabs activeTab = { activeTab } onTabChange = { handleTabChange } />
187122
188123 { /* Content based on active tab */ }
189124 { activeTab === 'ai' ? (
190125 < >
191126 { /* Emergency alert if needed */ }
192- { hasEmergency && (
193- < div className = "report-detail-page__emergency" >
194- < div className = "report-detail-page__emergency-icon" >
195- < svg
196- width = "20"
197- height = "20"
198- viewBox = "0 0 20 20"
199- fill = "none"
200- xmlns = "http://www.w3.org/2000/svg"
201- >
202- < path
203- d = "M9.25736 3.99072C9.52536 3.5167 10.1999 3.5167 10.4679 3.99072L17.8891 16.5347C18.1571 17.0087 17.8199 17.5999 17.2839 17.5999H2.44132C1.90536 17.5999 1.56816 17.0087 1.83616 16.5347L9.25736 3.99072Z"
204- stroke = "#C93A54"
205- strokeWidth = "1.5"
206- strokeLinecap = "round"
207- strokeLinejoin = "round"
208- />
209- < path
210- d = "M9.8623 7.20001V11.2"
211- stroke = "#C93A54"
212- strokeWidth = "1.5"
213- strokeLinecap = "round"
214- strokeLinejoin = "round"
215- />
216- < path
217- d = "M9.8623 14.4H9.87027"
218- stroke = "#C93A54"
219- strokeWidth = "1.5"
220- strokeLinecap = "round"
221- strokeLinejoin = "round"
222- />
223- </ svg >
224- </ div >
225- < p className = "report-detail-page__emergency-text" >
226- { t ( 'report.emergency.message' , { ns : 'reportDetail' } ) }
227- </ p >
228- </ div >
229- ) }
127+ { hasEmergency && < EmergencyAlert /> }
230128
231129 { /* Flagged values section */ }
232- < div className = "report-detail-page__section" >
233- < div className = "report-detail-page__section-header" onClick = { toggleFlaggedValues } >
234- < div className = "report-detail-page__section-icon" >
235- < Icon icon = "flag" size = "sm" style = { { color : '#c93a54' } } />
236- </ div >
237- < h3 className = "report-detail-page__section-title" >
238- { t ( 'report.flagged-values.title' , { ns : 'reportDetail' } ) }
239- </ h3 >
240- < div className = "report-detail-page__section-toggle" >
241- < Icon icon = { flaggedValuesExpanded ? 'chevronUp' : 'chevronDown' } size = "sm" />
242- </ div >
243- </ div >
244-
245- { flaggedValuesExpanded &&
246- flaggedValues . map ( ( item : LabValue , index ) => (
247- < div key = { index } className = "report-detail-page__item" >
248- < div
249- className = { `report-detail-page__item-header report-detail-page__item-header--${ item . status . toLowerCase ( ) } ` }
250- >
251- < div className = "report-detail-page__item-name" > { item . name } </ div >
252- < div
253- className = { `report-detail-page__item-level report-detail-page__item-level--${ item . status . toLowerCase ( ) } ` }
254- >
255- { item . status }
256- </ div >
257- < div className = "report-detail-page__item-value" >
258- { item . value } { item . unit }
259- </ div >
260- </ div >
261- < div className = "report-detail-page__item-details" >
262- < div className = "report-detail-page__item-section" >
263- < h4 > { t ( 'report.conclusion.title' , { ns : 'reportDetail' } ) } :</ h4 >
264- < p > { item . conclusion } </ p >
265- </ div >
266- < div className = "report-detail-page__item-section" >
267- < h4 > { t ( 'report.suggestions.title' , { ns : 'reportDetail' } ) } :</ h4 >
268- < p > { item . suggestions } </ p >
269- </ div >
270- </ div >
271- </ div >
272- ) ) }
273- </ div >
130+ < FlaggedValuesSection
131+ flaggedValues = { flaggedValues }
132+ isExpanded = { flaggedValuesExpanded }
133+ onToggle = { toggleFlaggedValues }
134+ />
274135
275136 { /* Normal values section */ }
276- < div className = "report-detail-page__section" >
277- < div className = "report-detail-page__section-header" onClick = { toggleNormalValues } >
278- < div
279- className = "report-detail-page__section-icon"
280- style = { { borderRadius : '50%' , backgroundColor : '#f0f0f0' } }
281- >
282- < Icon icon = "vial" size = "sm" />
283- </ div >
284- < h3 className = "report-detail-page__section-title" >
285- { t ( 'report.normal-values.title' , { ns : 'reportDetail' } ) }
286- </ h3 >
287- < div className = "report-detail-page__section-toggle" >
288- < Icon icon = { normalValuesExpanded ? 'chevronUp' : 'chevronDown' } size = "sm" />
289- </ div >
290- </ div >
291-
292- { normalValuesExpanded &&
293- normalValues . map ( ( item : LabValue , index ) => (
294- < div key = { index } className = "report-detail-page__item" >
295- < div className = "report-detail-page__item-header" >
296- < div className = "report-detail-page__item-name" > { item . name } </ div >
297- < div className = "report-detail-page__item-value" >
298- { item . value } { item . unit }
299- </ div >
300- </ div >
301- < div className = "report-detail-page__item-details" >
302- < div className = "report-detail-page__item-section" >
303- < h4 > { t ( 'report.conclusion.title' , { ns : 'reportDetail' } ) } :</ h4 >
304- < p > { item . conclusion } </ p >
305- </ div >
306- < div className = "report-detail-page__item-section" >
307- < h4 > { t ( 'report.suggestions.title' , { ns : 'reportDetail' } ) } :</ h4 >
308- < p > { item . suggestions } </ p >
309- </ div >
310- </ div >
311- </ div >
312- ) ) }
313- </ div >
137+ < NormalValuesSection
138+ normalValues = { normalValues }
139+ isExpanded = { normalValuesExpanded }
140+ onToggle = { toggleNormalValues }
141+ />
314142 </ >
315143 ) : (
316144 /* Original Report Tab Content */
317- < div className = "report-detail-page__original-report" >
318- { /* Test results table */ }
319- < div className = "report-detail-page__results-table" >
320- < div className = "report-detail-page__results-header" >
321- < div className = "report-detail-page__results-cell report-detail-page__results-cell--test" >
322- Test
323- </ div >
324- < div className = "report-detail-page__results-cell report-detail-page__results-cell--value" >
325- Results
326- </ div >
327- < div className = "report-detail-page__results-cell report-detail-page__results-cell--ref" >
328- Ref.
329- </ div >
330- </ div >
331-
332- { /* Test Results Rows */ }
333- { reportData . labValues . map ( ( labValue , index ) => (
334- < div
335- key = { index }
336- className = { `report-detail-page__results-row ${
337- labValue . status !== 'normal' ? 'report-detail-page__results-row--flagged' : ''
338- } `}
339- >
340- < div className = "report-detail-page__results-cell report-detail-page__results-cell--test" >
341- { labValue . name }
342- </ div >
343- < div className = "report-detail-page__results-cell report-detail-page__results-cell--value" >
344- { labValue . value } { labValue . unit }
345- </ div >
346- < div className = "report-detail-page__results-cell report-detail-page__results-cell--ref" >
347- { labValue . normalRange }
348- </ div >
349- </ div >
350- ) ) }
351- </ div >
352-
353- { /* Uploaded File Section */ }
354- < div className = "report-detail-page__uploaded-file" >
355- < h4 className = "report-detail-page__uploaded-file-title" > Uploaded file</ h4 >
356- < div className = "report-detail-page__file-container" >
357- < div className = "report-detail-page__file-icon" >
358- < Icon icon = "filePdf" />
359- </ div >
360- < div className = "report-detail-page__file-details" >
361- < div className = "report-detail-page__file-name" >
362- { reportData . filePath . split ( '/' ) . pop ( ) || 'Exam_11_01_2024.pdf' }
363- </ div >
364- < div className = "report-detail-page__file-info" >
365- < span className = "report-detail-page__file-size" > 92 kb</ span >
366- < span className = "report-detail-page__file-separator" > •</ span >
367- < span className = "report-detail-page__file-date" >
368- Uploaded ({ format ( new Date ( reportData . createdAt ) , 'MM/dd/yyyy' ) } )
369- </ span >
370- </ div >
371- </ div >
372- </ div >
373- </ div >
374- </ div >
145+ < OriginalReport reportData = { reportData } />
375146 ) }
376147
377148 { /* Doctor information note */ }
378- < div className = "report-detail-page__info-card" >
379- < div className = "report-detail-page__info-icon" >
380- < Icon icon = "circleInfo" />
381- </ div >
382- < div className = "report-detail-page__info-text" >
383- { t ( 'report.doctor-note' , { ns : 'reportDetail' } ) }
384- </ div >
385- </ div >
149+ < InfoCard />
386150
387151 { /* Action buttons at the bottom */ }
388- < div className = "report-detail-page__actions" >
389- < button
390- className = "report-detail-page__action-button report-detail-page__action-button--discard"
391- onClick = { handleDiscard }
392- >
393- { t ( 'report.action.discard' , { ns : 'reportDetail' } ) }
394- </ button >
395- < button
396- className = "report-detail-page__action-button report-detail-page__action-button--upload"
397- onClick = { handleNewUpload }
398- >
399- { t ( 'report.action.new-upload' , { ns : 'reportDetail' } ) }
400- </ button >
401- </ div >
152+ < ActionButtons onDiscard = { handleDiscard } onNewUpload = { handleNewUpload } />
402153 </ IonContent >
403154 </ IonPage >
404155 ) ;
0 commit comments