Skip to content

Commit af1b4a5

Browse files
authored
Merge pull request #163 from ModusCreateOrg/ADE-200-Adam
[ADE-200] UI fixes
2 parents 3d8da77 + f9fd5be commit af1b4a5

18 files changed

+191
-143
lines changed

frontend/src/assets/icons/back.svg

Lines changed: 5 additions & 0 deletions
Loading

frontend/src/common/hooks/useChat.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ export function useChat(sessionId?: string) {
2121
// Mutation for creating a new session
2222
const createSession = useMutation({
2323
mutationFn: () => bedrockService.createChatSession(),
24-
onSuccess: (newSessionId) => {
25-
queryClient.invalidateQueries({ queryKey: [QueryKey.Chat, 'sessions'] });
24+
onSuccess: async (newSessionId) => {
25+
await queryClient.invalidateQueries({ queryKey: [QueryKey.Chat, 'sessions'] });
2626
return newSessionId;
2727
},
2828
});
@@ -33,9 +33,9 @@ export function useChat(sessionId?: string) {
3333
if (!sessionId) throw new Error('No active session');
3434
return bedrockService.sendMessage(sessionId, message);
3535
},
36-
onSuccess: () => {
37-
queryClient.invalidateQueries({ queryKey: [QueryKey.Chat, sessionId] });
38-
queryClient.invalidateQueries({ queryKey: [QueryKey.Chat, 'sessions'] });
36+
onSuccess: async () => {
37+
await queryClient.invalidateQueries({ queryKey: [QueryKey.Chat, sessionId] });
38+
await queryClient.invalidateQueries({ queryKey: [QueryKey.Chat, 'sessions'] });
3939
},
4040
});
4141

frontend/src/pages/Auth/SignIn/api/useSignIn.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,9 @@ export const useSignIn = () => {
6060

6161
return useMutation({
6262
mutationFn: signIn,
63-
onSuccess: () => {
64-
queryClient.invalidateQueries({ queryKey: [QueryKey.UserTokens] });
65-
queryClient.invalidateQueries({ queryKey: [QueryKey.Users, 'current'] });
63+
onSuccess: async () => {
64+
await queryClient.invalidateQueries({ queryKey: [QueryKey.UserTokens] });
65+
await queryClient.invalidateQueries({ queryKey: [QueryKey.Users, 'current'] });
6666
},
6767
});
6868
};

frontend/src/pages/Processing/ProcessingPage.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,12 @@ const ProcessingPage: React.FC = () => {
7373

7474
console.log('Processing complete');
7575

76-
queryClient.invalidateQueries({ queryKey: [QueryKey.Reports] });
77-
queryClient.invalidateQueries({ queryKey: [QueryKey.LatestReports] });
76+
await queryClient.invalidateQueries({ queryKey: [QueryKey.Reports] });
77+
await queryClient.invalidateQueries({ queryKey: [QueryKey.LatestReports] });
7878

79-
history.push(`/tabs/reports/${reportId}`);
79+
history.push(`/tabs/reports/${reportId}`, {
80+
from: location.pathname,
81+
});
8082
} else if (data.status === 'failed') {
8183
if (data.isMedicalReport === false) {
8284
setIsProcessing(false);

frontend/src/pages/ReportDetail/ReportDetailPage.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,19 @@
2525
color: #313e4c;
2626
}
2727

28+
&__back-button {
29+
border: none;
30+
background: transparent;
31+
color: #435ff0;
32+
font-size: 24px;
33+
padding: 0;
34+
cursor: pointer;
35+
display: flex;
36+
align-items: center;
37+
margin-right: 0.9em;
38+
margin-bottom: 1em;
39+
}
40+
2841
&__close-button {
2942
border: none;
3043
background: transparent;

frontend/src/pages/ReportDetail/ReportDetailPage.tsx

Lines changed: 27 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import { IonPage, IonContent } from '@ionic/react';
2-
import { useState } from 'react';
2+
import { FC, useState } from 'react';
33
import { useHistory, useParams } from 'react-router-dom';
44
import './ReportDetailPage.scss';
5-
import { useQuery, useQueryClient } from '@tanstack/react-query';
5+
import { useQuery } from '@tanstack/react-query';
66
import axios from 'axios';
77
import { MedicalReport } from '../../common/models/medicalReport';
88
import { useTranslation } from 'react-i18next';
99
import { getAuthConfig } from 'common/api/reportService';
10-
import { useToasts } from 'common/hooks/useToasts';
1110
import AiAssistantNotice from './components/AiAssistantNotice';
1211
import ReportHeader from './components/ReportHeader';
1312
import ReportTabs from './components/ReportTabs';
@@ -20,42 +19,47 @@ import { QueryKey } from 'common/utils/constants';
2019

2120
const API_URL = import.meta.env.VITE_BASE_URL_API || '';
2221

23-
// Function to fetch report by ID
24-
const fetchReportById = async (id: string): Promise<MedicalReport> => {
25-
const response = await axios.get<MedicalReport>(
26-
`${API_URL}/api/reports/${id}`,
27-
await getAuthConfig(),
28-
);
29-
return response.data;
30-
};
31-
3222
/**
3323
* Page component for displaying detailed medical report analysis.
3424
* This shows AI insights and original report data with flagged values.
3525
*/
36-
const ReportDetailPage: React.FC = () => {
26+
const ReportDetailPage: FC = () => {
3727
const { reportId } = useParams<{ reportId: string }>();
3828
const history = useHistory();
3929
const { t } = useTranslation();
40-
const { createToast } = useToasts();
4130
const [isUploadModalOpen, setIsUploadModalOpen] = useState(false);
42-
const queryClient = useQueryClient();
31+
const [activeTab, setActiveTab] = useState<'ai' | 'original'>('ai');
4332

4433
const handleUploadComplete = () => {
4534
setIsUploadModalOpen(false);
4635
history.push('/tabs/home');
4736
};
4837

38+
// Handle tab selection
39+
const handleTabChange = (tab: 'ai' | 'original') => {
40+
setActiveTab(tab);
41+
};
42+
43+
// Function to fetch report by ID
44+
const fetchReportById = async (id: string): Promise<MedicalReport> => {
45+
const response = await axios.get<MedicalReport>(
46+
`${API_URL}/api/reports/${id}`,
47+
await getAuthConfig(),
48+
);
49+
return response.data;
50+
};
51+
4952
// Fetch report data using react-query
50-
const { data, isLoading, error } = useQuery<MedicalReport>({
53+
const {
54+
data: reportData,
55+
isLoading,
56+
error,
57+
} = useQuery<MedicalReport>({
5158
queryKey: [QueryKey.ReportDetail, reportId],
5259
queryFn: () => fetchReportById(reportId!),
5360
enabled: !!reportId,
5461
});
5562

56-
// State to track expanded sections
57-
const [activeTab, setActiveTab] = useState<'ai' | 'original'>('ai');
58-
5963
// Handle loading and error states
6064
if (isLoading) {
6165
return <IonPage></IonPage>;
@@ -71,7 +75,7 @@ const ReportDetailPage: React.FC = () => {
7175
);
7276
}
7377

74-
if (!data) {
78+
if (!reportData) {
7579
return (
7680
<IonPage>
7781
<IonContent className="ion-padding">
@@ -81,77 +85,11 @@ const ReportDetailPage: React.FC = () => {
8185
);
8286
}
8387

84-
const reportData = data;
85-
86-
// Handle tab selection
87-
const handleTabChange = (tab: 'ai' | 'original') => {
88-
setActiveTab(tab);
89-
};
90-
91-
// Handle close button
92-
const handleClose = () => {
93-
history.push('/tabs/home');
94-
};
95-
96-
// Handle action buttons
97-
const handleDiscard = async (setIsProcessing: (isProcessing: boolean) => void) => {
98-
try {
99-
setIsProcessing(true);
100-
await axios.delete(`${API_URL}/api/reports/${reportId}`, await getAuthConfig());
101-
setIsProcessing(false);
102-
103-
// Show toast notification
104-
createToast({
105-
message: t('report.discard.success', {
106-
ns: 'reportDetail',
107-
defaultValue: 'Report deleted successfully',
108-
}),
109-
duration: 2000,
110-
});
111-
112-
queryClient.invalidateQueries({ queryKey: [QueryKey.Reports] });
113-
queryClient.invalidateQueries({ queryKey: [QueryKey.LatestReports] });
114-
queryClient.invalidateQueries({ queryKey: [QueryKey.ReportDetail, reportId] });
115-
116-
// Navigate back
117-
history.push('/tabs/home');
118-
} catch (error) {
119-
setIsProcessing(false);
120-
121-
console.error('Error discarding report:', error);
122-
createToast({
123-
message: t('report.discard.error', {
124-
ns: 'reportDetail',
125-
defaultValue: 'Failed to delete report',
126-
}),
127-
duration: 2000,
128-
color: 'danger',
129-
});
130-
}
131-
};
132-
133-
const handleNewUpload = async (setIsProcessing: (isProcessing: boolean) => void) => {
134-
try {
135-
setIsProcessing(true);
136-
await axios.delete(`${API_URL}/api/reports/${reportId}`, await getAuthConfig());
137-
setIsProcessing(false);
138-
139-
queryClient.invalidateQueries({ queryKey: [QueryKey.Reports] });
140-
queryClient.invalidateQueries({ queryKey: [QueryKey.LatestReports] });
141-
queryClient.invalidateQueries({ queryKey: [QueryKey.ReportDetail, reportId] });
142-
143-
setIsUploadModalOpen(true);
144-
} catch (error) {
145-
setIsProcessing(false);
146-
console.error('Error deleting report before new upload:', error);
147-
}
148-
};
149-
15088
return (
15189
<IonPage className="report-detail-page">
15290
<IonContent fullscreen>
15391
{/* Header component */}
154-
<ReportHeader reportData={reportData} onClose={handleClose} />
92+
<ReportHeader reportData={reportData} />
15593

15694
{/* Tab selector for AI Insights vs Original Report */}
15795
<ReportTabs activeTab={activeTab} onTabChange={handleTabChange} />
@@ -172,9 +110,9 @@ const ReportDetailPage: React.FC = () => {
172110

173111
{/* Action buttons at the bottom */}
174112
<ActionButtons
175-
onDiscard={handleDiscard}
176-
onNewUpload={handleNewUpload}
113+
reportId={reportId}
177114
reportTitle={reportData.title}
115+
setIsUploadModalOpen={setIsUploadModalOpen}
178116
/>
179117

180118
<UploadModal

frontend/src/pages/ReportDetail/components/ActionButtons.tsx

Lines changed: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
1-
import React, { useState } from 'react';
1+
import { FC, useState } from 'react';
22
import { useTranslation } from 'react-i18next';
33
import ConfirmationModal from '../../../common/components/Modal/ConfirmationModal';
4+
import { useToasts } from 'common/hooks/useToasts';
5+
import { useQueryClient } from '@tanstack/react-query';
6+
import { useHistory } from 'react-router';
7+
import axios from 'axios';
8+
import { QueryKey } from 'common/utils/constants';
9+
import { getAuthConfig } from 'common/api/reportService';
10+
11+
const API_URL = import.meta.env.VITE_BASE_URL_API || '';
412

513
interface ActionButtonsProps {
6-
onDiscard: (setIsProcessing: (isProcessing: boolean) => void) => Promise<void>;
7-
onNewUpload: (setIsProcessing: (isProcessing: boolean) => void) => Promise<void>;
8-
reportTitle?: string;
9-
reportId?: string;
14+
reportId: string;
15+
reportTitle: string;
16+
setIsUploadModalOpen: (isOpen: boolean) => void;
1017
}
1118

12-
const ActionButtons: React.FC<ActionButtonsProps> = ({ onDiscard, onNewUpload, reportTitle }) => {
19+
const ActionButtons: FC<ActionButtonsProps> = ({ reportId, reportTitle, setIsUploadModalOpen }) => {
1320
const { t } = useTranslation(['reportDetail', 'common']);
21+
const { createToast } = useToasts();
22+
const history = useHistory();
23+
const queryClient = useQueryClient();
1424
const [showConfirmDiscard, setShowConfirmDiscard] = useState(false);
1525
const [showConfirmNewUpload, setShowConfirmNewUpload] = useState(false);
1626
const [isProcessing, setIsProcessing] = useState(false);
@@ -22,7 +32,7 @@ const ActionButtons: React.FC<ActionButtonsProps> = ({ onDiscard, onNewUpload, r
2232
const handleConfirmDiscard = async () => {
2333
setShowConfirmDiscard(false);
2434

25-
await onDiscard(setIsProcessing);
35+
await handleDiscard();
2636
};
2737

2838
const handleCancelDiscard = () => {
@@ -36,13 +46,67 @@ const ActionButtons: React.FC<ActionButtonsProps> = ({ onDiscard, onNewUpload, r
3646
const handleConfirmNewUpload = async () => {
3747
setShowConfirmNewUpload(false);
3848

39-
await onNewUpload(setIsProcessing);
49+
await handleNewUpload();
4050
};
4151

4252
const handleCancelNewUpload = () => {
4353
setShowConfirmNewUpload(false);
4454
};
4555

56+
// Handle action buttons
57+
const handleDiscard = async () => {
58+
try {
59+
setIsProcessing(true);
60+
await axios.delete(`${API_URL}/api/reports/${reportId}`, await getAuthConfig());
61+
setIsProcessing(false);
62+
63+
// Show toast notification
64+
createToast({
65+
message: t('report.discard.success', {
66+
ns: 'reportDetail',
67+
defaultValue: 'Report deleted successfully',
68+
}),
69+
duration: 2000,
70+
});
71+
72+
await queryClient.invalidateQueries({ queryKey: [QueryKey.Reports] });
73+
await queryClient.invalidateQueries({ queryKey: [QueryKey.LatestReports] });
74+
await queryClient.invalidateQueries({ queryKey: [QueryKey.ReportDetail, reportId] });
75+
76+
// Navigate back
77+
history.push('/tabs/home');
78+
} catch (error) {
79+
setIsProcessing(false);
80+
81+
console.error('Error discarding report:', error);
82+
createToast({
83+
message: t('report.discard.error', {
84+
ns: 'reportDetail',
85+
defaultValue: 'Failed to delete report',
86+
}),
87+
duration: 2000,
88+
color: 'danger',
89+
});
90+
}
91+
};
92+
93+
const handleNewUpload = async () => {
94+
try {
95+
setIsProcessing(true);
96+
await axios.delete(`${API_URL}/api/reports/${reportId}`, await getAuthConfig());
97+
setIsProcessing(false);
98+
99+
await queryClient.invalidateQueries({ queryKey: [QueryKey.Reports] });
100+
await queryClient.invalidateQueries({ queryKey: [QueryKey.LatestReports] });
101+
await queryClient.invalidateQueries({ queryKey: [QueryKey.ReportDetail, reportId] });
102+
103+
setIsUploadModalOpen(true);
104+
} catch (error) {
105+
setIsProcessing(false);
106+
console.error('Error deleting report before new upload:', error);
107+
}
108+
};
109+
46110
return (
47111
<>
48112
<div className="report-detail-page__actions">

frontend/src/pages/ReportDetail/components/AiAnalysisTab.tsx

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import { FC, useState } from 'react';
22
import { MedicalReport, LabValue } from '../../../common/models/medicalReport';
33
import EmergencyAlert from './EmergencyAlert';
44
import FlaggedValuesSection from './FlaggedValuesSection';
@@ -10,13 +10,10 @@ interface AiAnalysisTabProps {
1010
isEmergencyAlertVisible?: boolean;
1111
}
1212

13-
const AiAnalysisTab: React.FC<AiAnalysisTabProps> = ({
14-
reportData,
15-
isEmergencyAlertVisible = true,
16-
}) => {
13+
const AiAnalysisTab: FC<AiAnalysisTabProps> = ({ reportData, isEmergencyAlertVisible = true }) => {
1714
// State to track expanded sections
18-
const [flaggedValuesExpanded, setFlaggedValuesExpanded] = React.useState(true);
19-
const [normalValuesExpanded, setNormalValuesExpanded] = React.useState(true);
15+
const [flaggedValuesExpanded, setFlaggedValuesExpanded] = useState(true);
16+
const [normalValuesExpanded, setNormalValuesExpanded] = useState(true);
2017

2118
// Toggle expanded state of sections
2219
const toggleFlaggedValues = () => setFlaggedValuesExpanded(!flaggedValuesExpanded);

0 commit comments

Comments
 (0)