Skip to content

Commit e396e34

Browse files
authored
Merge pull request #125 from ModusCreateOrg/ADE-67
[ADE-67] Discard and Upload new Report functionality
2 parents 1d2f84c + 92746cb commit e396e34

File tree

7 files changed

+311
-25
lines changed

7 files changed

+311
-25
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
.confirmation-modal {
2+
--height: auto;
3+
--border-radius: 16px 16px 0 0;
4+
--box-shadow: none;
5+
align-items: flex-end;
6+
--background: #ffffff;
7+
8+
&__container {
9+
padding: 24px;
10+
width: 100%;
11+
}
12+
13+
&__title {
14+
font-family: 'Inter', sans-serif;
15+
font-size: 22px;
16+
font-weight: 600;
17+
color: #313e4c;
18+
margin: 0 0 16px;
19+
text-align: left;
20+
}
21+
22+
&__message {
23+
font-family: 'Inter', sans-serif;
24+
font-size: 16px;
25+
font-weight: 400;
26+
color: #313e4c;
27+
margin: 0 0 24px;
28+
text-align: left;
29+
line-height: 1.5;
30+
}
31+
32+
&__actions {
33+
display: flex;
34+
gap: 16px;
35+
}
36+
37+
&__button {
38+
flex: 1;
39+
min-height: 56px;
40+
margin: 0;
41+
--border-radius: 12px;
42+
font-size: 20px;
43+
font-weight: 600;
44+
text-transform: none;
45+
46+
&--cancel {
47+
--background: #ffffff;
48+
--background-hover: rgba(67, 95, 240, 0.04);
49+
--background-activated: rgba(67, 95, 240, 0.08);
50+
--color: #435ff0; /* Blue color for No button */
51+
--border-color: #435ff0;
52+
--border-width: 1px;
53+
--border-style: solid;
54+
--box-shadow: none;
55+
}
56+
57+
&--confirm {
58+
--background: #ffffff; /* White background for Yes button */
59+
--background-hover: rgba(175, 27, 63, 0.04);
60+
--background-activated: rgba(175, 27, 63, 0.08);
61+
--color: #af1b3f; /* Red color for Yes button */
62+
--border-color: #af1b3f; /* Red border for Yes button */
63+
--border-width: 1px;
64+
--border-style: solid;
65+
}
66+
}
67+
68+
// Media queries for larger screens
69+
@media screen and (min-width: 768px) {
70+
&__container {
71+
max-width: 500px;
72+
margin: 0 auto;
73+
}
74+
}
75+
76+
// Handle the pull indicator
77+
&::part(handle) {
78+
background: #D9D9D9;
79+
width: 36px;
80+
height: 4px;
81+
border-radius: 2px;
82+
margin-top: 12px;
83+
}
84+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import React from 'react';
2+
import { IonButton, IonModal } from '@ionic/react';
3+
import './ConfirmationModal.scss';
4+
5+
interface ConfirmationModalProps {
6+
isOpen: boolean;
7+
title: string;
8+
message: string;
9+
confirmText: string;
10+
cancelText: string;
11+
onConfirm: () => void;
12+
onCancel: () => void;
13+
itemName?: string;
14+
testid?: string;
15+
}
16+
17+
/**
18+
* A reusable confirmation modal component that presents as a bottom sheet
19+
* Used for confirming destructive actions like deleting or discarding items
20+
*/
21+
const ConfirmationModal: React.FC<ConfirmationModalProps> = ({
22+
isOpen,
23+
title,
24+
message,
25+
confirmText,
26+
cancelText,
27+
onConfirm,
28+
onCancel,
29+
itemName,
30+
testid = 'confirmation-modal',
31+
}) => {
32+
// Replace placeholder with actual item name if provided
33+
const formattedMessage = itemName
34+
? message.replace('{itemName}', `"${itemName}"`)
35+
: message;
36+
37+
return (
38+
<IonModal
39+
isOpen={isOpen}
40+
onDidDismiss={onCancel}
41+
className="confirmation-modal"
42+
data-testid={testid}
43+
>
44+
<div className="confirmation-modal__container">
45+
<h2 className="confirmation-modal__title">{title}</h2>
46+
47+
<p className="confirmation-modal__message">
48+
{formattedMessage}
49+
</p>
50+
51+
<div className="confirmation-modal__actions">
52+
<IonButton
53+
expand="block"
54+
fill="outline"
55+
className="confirmation-modal__button confirmation-modal__button--cancel"
56+
onClick={onCancel}
57+
data-testid={`${testid}-cancel`}
58+
>
59+
{cancelText}
60+
</IonButton>
61+
62+
<IonButton
63+
expand="block"
64+
fill="outline"
65+
className="confirmation-modal__button confirmation-modal__button--confirm"
66+
onClick={onConfirm}
67+
data-testid={`${testid}-confirm`}
68+
>
69+
{confirmText}
70+
</IonButton>
71+
</div>
72+
</div>
73+
</IonModal>
74+
);
75+
};
76+
77+
export default ConfirmationModal;

frontend/src/common/utils/i18n/resources/en/common.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@
7373
"loading": {
7474
"report": "Loading report..."
7575
},
76-
"no": "no",
76+
"no": "No",
7777
"updated": "updated",
7878
"welcome": "Welcome",
79-
"yes": "yes",
79+
"yes": "Yes",
8080
"pages": {
8181
"chat": {
8282
"title": "AI Assistant"

frontend/src/common/utils/i18n/resources/es/common.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@
7070
"loading": {
7171
"report": "Cargando informe..."
7272
},
73-
"no": "no",
73+
"no": "No",
7474
"updated": "actualizado",
7575
"welcome": "Bienvenido",
76-
"yes": "",
76+
"yes": "",
7777
"pages": {
7878
"chat": {
7979
"title": "Asistente IA"

frontend/src/common/utils/i18n/resources/fr/common.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@
7070
"loading": {
7171
"report": "Chargement du rapport..."
7272
},
73-
"no": "non",
73+
"no": "Non",
7474
"updated": "mis à jour",
7575
"welcome": "Bienvenu",
76-
"yes": "oui",
76+
"yes": "Oui",
7777
"pages": {
7878
"chat": {
7979
"title": "Assistant IA"

frontend/src/pages/Reports/ReportDetailPage.tsx

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ 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';
1011

1112
// Import components
1213
import ReportHeader from './components/ReportHeader';
@@ -35,6 +36,7 @@ const ReportDetailPage: React.FC = () => {
3536
const { reportId } = useParams<{ reportId: string }>();
3637
const history = useHistory();
3738
const { t } = useTranslation();
39+
const { createToast } = useToasts();
3840

3941
// Fetch report data using react-query
4042
const { data, isLoading, error } = useQuery<MedicalReport>({
@@ -85,8 +87,31 @@ const ReportDetailPage: React.FC = () => {
8587

8688
// Handle action buttons
8789
const handleDiscard = async () => {
88-
await axios.delete(`${API_URL}/api/reports/${reportId}`, await getAuthConfig());
89-
history.push('/tabs/home');
90+
try {
91+
await axios.delete(`${API_URL}/api/reports/${reportId}`, await getAuthConfig());
92+
93+
// Show toast notification
94+
createToast({
95+
message: t('report.discard.success', {
96+
ns: 'reportDetail',
97+
defaultValue: 'Report deleted successfully',
98+
}),
99+
duration: 2000,
100+
});
101+
102+
// Navigate back
103+
history.push('/tabs/home');
104+
} catch (error) {
105+
console.error('Error discarding report:', error);
106+
createToast({
107+
message: t('report.discard.error', {
108+
ns: 'reportDetail',
109+
defaultValue: 'Failed to delete report',
110+
}),
111+
duration: 2000,
112+
color: 'danger',
113+
});
114+
}
90115
};
91116

92117
const handleNewUpload = () => {
@@ -114,7 +139,12 @@ const ReportDetailPage: React.FC = () => {
114139
<InfoCard />
115140

116141
{/* Action buttons at the bottom */}
117-
<ActionButtons onDiscard={handleDiscard} onNewUpload={handleNewUpload} />
142+
<ActionButtons
143+
onDiscard={handleDiscard}
144+
onNewUpload={handleNewUpload}
145+
reportTitle={reportData.title || reportData.category}
146+
reportId={reportId}
147+
/>
118148
</IonContent>
119149
</IonPage>
120150
);

0 commit comments

Comments
 (0)