Skip to content

Commit 5f5b72b

Browse files
authored
Merge pull request #98 from ModusCreateOrg/ADE-198
[ADE-198] Create Filter modal
2 parents be95062 + 9ed541e commit 5f5b72b

File tree

12 files changed

+450
-115
lines changed

12 files changed

+450
-115
lines changed

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

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,20 @@
4949
"filterBookmarked": "Bookmarked",
5050
"noBookmarksTitle": "No Bookmarked Reports",
5151
"noBookmarksMessage": "Bookmark reports to find them quickly here",
52+
"noMatchesTitle": "No Matching Reports",
53+
"noMatchesMessage": "No reports match your current filters. Try changing or clearing your filters.",
54+
"clearFilters": "Clear Filters",
5255
"sortButton": "Sort reports",
53-
"filterButton": "Filter reports",
54-
"generalCategory": "General",
55-
"brainCategory": "Brain",
56-
"heartCategory": "Heart"
56+
"filterButton": "Filter reports"
57+
},
58+
"filter": {
59+
"title": "Filter",
60+
"category": "Category",
61+
"apply": "Apply"
62+
},
63+
"category": {
64+
"general": "General",
65+
"heart": "Heart",
66+
"brain": "Brain"
5767
}
5868
}

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@
4848
"filterAll": "Todos",
4949
"filterBookmarked": "Guardados",
5050
"noBookmarksTitle": "No Hay Informes Guardados",
51-
"noBookmarksMessage": "Guarda informes como favoritos para encontrarlos rápidamente aquí"
51+
"noBookmarksMessage": "Guarda informes como favoritos para encontrarlos rápidamente aquí",
52+
"noMatchesTitle": "No Hay Informes Coincidentes",
53+
"noMatchesMessage": "Ningún informe coincide con los filtros actuales. Intenta cambiar o eliminar los filtros.",
54+
"clearFilters": "Eliminar Filtros",
55+
"sortButton": "Ordenar informes",
56+
"filterButton": "Filtrar informes"
57+
},
58+
"filter": {
59+
"title": "Filtrar",
60+
"category": "Categoría",
61+
"apply": "Aplicar"
62+
},
63+
"category": {
64+
"general": "General",
65+
"heart": "Corazón",
66+
"brain": "Cerebro"
5267
}
5368
}

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@
4848
"filterAll": "Tous",
4949
"filterBookmarked": "Favoris",
5050
"noBookmarksTitle": "Aucun Rapport en Favoris",
51-
"noBookmarksMessage": "Marquez des rapports comme favoris pour les trouver rapidement ici"
51+
"noBookmarksMessage": "Marquez des rapports comme favoris pour les trouver rapidement ici",
52+
"noMatchesTitle": "Aucun Rapport Correspondant",
53+
"noMatchesMessage": "Aucun rapport ne correspond à vos filtres actuels. Essayez de modifier ou de supprimer vos filtres.",
54+
"clearFilters": "Effacer les Filtres",
55+
"sortButton": "Trier les rapports",
56+
"filterButton": "Filtrer les rapports"
57+
},
58+
"filter": {
59+
"title": "Filtrer",
60+
"category": "Catégorie",
61+
"apply": "Appliquer"
62+
},
63+
"category": {
64+
"general": "Général",
65+
"heart": "Cœur",
66+
"brain": "Cerveau"
5267
}
5368
}

frontend/src/pages/Home/HomePage.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ import { useHistory } from 'react-router-dom';
1414
import { useState } from 'react';
1515
import { useGetLatestReports, useMarkReportAsRead } from 'common/hooks/useReports';
1616
import { useCurrentUser } from 'common/hooks/useAuth';
17+
import { toggleReportBookmark } from 'common/api/reportService';
18+
import { useQueryClient } from '@tanstack/react-query';
19+
import { MedicalReport } from 'common/models/medicalReport';
1720
import Avatar from 'common/components/Icon/Avatar';
1821
import ReportItem from './components/ReportItem/ReportItem';
1922
import NoReportsMessage from './components/NoReportsMessage/NoReportsMessage';
@@ -27,6 +30,7 @@ import './HomePage.scss';
2730
const HomePage: React.FC = () => {
2831
const { t } = useTranslation('home');
2932
const history = useHistory();
33+
const queryClient = useQueryClient();
3034
const { data: reports, isLoading, isError } = useGetLatestReports(3);
3135
const { mutate: markAsRead } = useMarkReportAsRead();
3236
const currentUser = useCurrentUser();
@@ -43,6 +47,31 @@ const HomePage: React.FC = () => {
4347
history.push(`/tabs/reports/${reportId}`);
4448
};
4549

50+
const handleToggleBookmark = async (reportId: string, isCurrentlyBookmarked: boolean) => {
51+
try {
52+
// Toggle the bookmark status
53+
const updatedReport = await toggleReportBookmark(reportId, !isCurrentlyBookmarked);
54+
55+
// Update the reports in the cache
56+
queryClient.setQueryData<MedicalReport[]>(['reports'], (oldReports) => {
57+
if (!oldReports) return [];
58+
return oldReports.map((report) =>
59+
report.id === updatedReport.id ? updatedReport : report,
60+
);
61+
});
62+
63+
// Update the latest reports cache with the correct query key including the limit
64+
queryClient.setQueryData<MedicalReport[]>(['latestReports', 3], (oldReports) => {
65+
if (!oldReports) return [];
66+
return oldReports.map((report) =>
67+
report.id === updatedReport.id ? updatedReport : report,
68+
);
69+
});
70+
} catch (error) {
71+
console.error('Failed to toggle bookmark:', error);
72+
}
73+
};
74+
4675
const handleUpload = () => {
4776
history.push('/upload');
4877
};
@@ -92,6 +121,7 @@ const HomePage: React.FC = () => {
92121
key={report.id}
93122
report={report}
94123
onClick={() => handleReportClick(report.id)}
124+
onToggleBookmark={() => handleToggleBookmark(report.id, report.bookmarked)}
95125
showBookmarkButton={true}
96126
/>
97127
));

frontend/src/pages/Home/components/ReportItem/ReportItem.scss

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
padding: 16px;
44
border-radius: 12px;
55
margin-bottom: 12px;
6-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
76
position: relative;
87
cursor: pointer;
98

@@ -67,6 +66,7 @@
6766
&--active {
6867
color: white;
6968
background-color: #4355b9;
69+
box-shadow: none;
7070
}
7171
}
7272
}
@@ -81,7 +81,6 @@
8181
flex-shrink: 0;
8282
background-color: white;
8383
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
84-
border: 1px solid rgba(0, 0, 0, 0.03);
8584

8685
&--general,
8786
&--brain,

frontend/src/pages/Home/components/ReportItem/ReportItem.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ const ReportItem: React.FC<ReportItemProps> = ({
3939
// Get category translation key based on category value
4040
const getCategoryTranslationKey = () => {
4141
if (categoryStr === ReportCategory.GENERAL.toLowerCase()) {
42-
return 'list.generalCategory';
42+
return 'category.general';
4343
} else if (categoryStr === ReportCategory.BRAIN.toLowerCase()) {
44-
return 'list.brainCategory';
44+
return 'category.brain';
4545
} else if (categoryStr === ReportCategory.HEART.toLowerCase()) {
46-
return 'list.heartCategory';
46+
return 'category.heart';
4747
}
48-
return 'list.generalCategory'; // Default to general if not found
48+
return 'category.general'; // Default to general if not found
4949
};
5050

5151
// Get the appropriate icon for the category

frontend/src/pages/Reports/ReportsListPage.scss

Lines changed: 59 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -19,150 +19,116 @@
1919
}
2020

2121
&__title-icon {
22-
margin-right: 12px;
23-
color: #333;
24-
padding: 8px;
25-
background-color: #f0f2f5;
26-
border-radius: 50%;
27-
display: flex;
28-
align-items: center;
29-
justify-content: center;
30-
width: 18px;
31-
height: 18px;
22+
font-size: 1.5rem;
23+
margin-right: 0.5rem;
24+
color: var(--ion-color-primary);
3225
}
3326

3427
&__title {
35-
font-size: 18px;
28+
font-size: 1.25rem;
3629
font-weight: 600;
3730
margin: 0;
38-
color: #333;
3931
}
4032

4133
&__actions {
4234
display: flex;
4335
align-items: center;
44-
justify-content: flex-end;
4536
}
4637

4738
&__sort-button,
4839
&__filter-button {
49-
--padding-start: 0;
50-
--padding-end: 0;
40+
--padding-start: 0.5rem;
41+
--padding-end: 0.5rem;
42+
margin: 0;
5143
height: 36px;
52-
width: 36px;
53-
--background: transparent;
54-
--color: #4355b9;
55-
--box-shadow: none;
56-
--ripple-color: transparent;
57-
margin-left: 10px;
58-
59-
.custom-icon-wrapper {
60-
width: 36px;
61-
height: 36px;
62-
display: flex;
63-
align-items: center;
64-
justify-content: center;
65-
border-radius: 50%;
66-
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
67-
border: 1px solid rgba(0, 0, 0, 0.03);
68-
}
44+
}
6945

70-
.custom-icon {
71-
width: 22px;
72-
height: 22px;
73-
}
46+
.custom-icon-wrapper {
47+
display: flex;
48+
align-items: center;
49+
justify-content: center;
7450
}
7551

76-
&__content-container {
77-
--padding-top: 0;
52+
.custom-icon {
53+
width: 20px;
54+
height: 20px;
7855
}
7956

8057
&__filter {
81-
padding: 8px 16px;
58+
margin-bottom: 1rem;
8259
}
8360

8461
&__segment-wrapper {
85-
ion-segment {
86-
--background: #ebeef9;
87-
border-radius: 50px;
88-
height: 40px;
89-
overflow: hidden;
90-
--border-radius: 50px;
91-
92-
ion-segment-button {
93-
--color: #777;
94-
--color-checked: #000;
95-
--indicator-color: white;
96-
--background-checked: white;
97-
--border-radius: 50px;
98-
--border-color: transparent;
99-
text-transform: none;
100-
font-weight: 500;
101-
letter-spacing: normal;
102-
font-size: 14px;
103-
min-height: 36px;
104-
105-
&::part(indicator) {
106-
border-radius: 50px;
107-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
108-
}
109-
}
110-
}
62+
padding: 0 1rem;
63+
}
64+
65+
&__category-tags {
66+
display: flex;
67+
flex-wrap: wrap;
68+
padding: 0.75rem 1rem;
69+
margin-bottom: 0.5rem;
70+
background-color: #f9f9f9;
71+
border-bottom: 1px solid var(--ion-color-light);
72+
}
73+
74+
&__content-container {
75+
--padding-top: 0;
76+
--background: var(--ion-background-color);
11177
}
11278

11379
&__content {
114-
padding: 0;
80+
padding-bottom: 1rem;
11581
}
11682

11783
&__list {
118-
background-color: transparent;
119-
padding: 12px;
120-
margin: 0;
121-
122-
ion-item {
123-
--padding-start: 0;
124-
--inner-padding-end: 0;
125-
--background: transparent;
126-
}
84+
padding: 0;
85+
background: transparent;
12786
}
12887

12988
&__empty-state {
130-
padding: 2rem;
89+
height: 100%;
13190
display: flex;
13291
flex-direction: column;
13392
align-items: center;
13493
justify-content: center;
94+
padding: 2rem;
13595
text-align: center;
13696
}
13797

138-
&__no-bookmarks {
139-
display: flex;
140-
flex-direction: column;
141-
align-items: center;
142-
justify-content: center;
98+
&__no-bookmarks,
99+
&__no-matches {
143100
text-align: center;
144-
padding: 2rem 1rem;
101+
padding: 2rem;
145102

146103
h3 {
147104
font-size: 1.2rem;
148-
margin-bottom: 0.5rem;
149-
color: #333;
150105
font-weight: 600;
106+
margin-bottom: 0.5rem;
151107
}
152108

153109
p {
154-
font-size: 0.9rem;
155-
color: #666;
156-
margin: 0;
110+
color: var(--ion-color-medium);
111+
margin-bottom: 1.5rem;
112+
}
113+
}
114+
115+
&__filter-modal {
116+
--height: auto;
117+
--width: 100%;
118+
--border-radius: 20px 20px 0 0;
119+
--box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.1);
120+
121+
&::part(content) {
122+
border-radius: 20px 20px 0 0;
157123
}
158124
}
159125

160-
// Skeleton loading styles
161126
.skeleton {
162-
width: 48px;
163-
height: 48px;
164-
border-radius: 50%;
165-
background-color: #ebeef9;
166-
margin-right: 16px;
127+
background-color: rgba(var(--ion-color-medium-rgb), 0.2);
128+
border-radius: 4px;
129+
height: 40px;
130+
width: 40px;
131+
margin-right: 1rem;
167132
}
168133
}
134+

0 commit comments

Comments
 (0)