Skip to content

Commit eb032b7

Browse files
authored
Merge pull request #59 from UTSC-CSCC01-Software-Engineering-I/develop
Develop mobile ui changes
2 parents 90a0bd2 + fa2aafd commit eb032b7

File tree

4 files changed

+215
-26
lines changed

4 files changed

+215
-26
lines changed

frontend/src/components/HUDleftPoints.jsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -444,21 +444,31 @@ function LogoBlock() {
444444
</button>
445445

446446
{showSortMenu && (
447-
<div style={{
447+
<div
448+
className="sort-menu"
449+
style={{
448450
position: 'absolute',
449451
top: 'calc(100% + 0.25rem)',
450452
right: 0,
451453
backgroundColor: theme === 'light' ? '#dadadae1' : '#242424f1',
452454
boxShadow: '0 2px 8px rgba(0,0,0,0.15)',
455+
456+
height: '20vh',
457+
453458
color: theme === 'light' ? '#000' : '#fff',
454459
borderRadius: '1rem',
455460
overflow: 'hidden',
461+
overflowY: 'scroll',
456462
zIndex: 10,
457463
width: '12rem',
458464
backdropFilter: 'blur(10px)',
459465
border: theme === 'light'
460466
? '1px solid rgba(255,255,255,0.3)'
461-
: '1px solid rgba(255,255,255,0.1)'
467+
: '1px solid rgba(255,255,255,0.1)',
468+
scrollbarWidth: 'thin',
469+
scrollbarColor: theme === 'light'
470+
? 'rgba(0,0,0,0.3) rgba(0,0,0,0.1)'
471+
: 'rgba(255,255,255,0.3) rgba(255,255,255,0.1)'
462472
}}>
463473
{/* Temperature sorting */}
464474
<div style={{ padding: '0.5rem 1rem', fontSize: '0.8rem', fontWeight: '600', borderBottom: '1px solid rgba(255,255,255,0.1)' }}>
@@ -636,6 +646,20 @@ function LogoBlock() {
636646
.boxwithpoints div::-webkit-scrollbar {
637647
display: none;
638648
}
649+
.sort-menu::-webkit-scrollbar {
650+
width: 8px;
651+
}
652+
.sort-menu::-webkit-scrollbar-track {
653+
background: ${theme === 'light' ? 'rgba(0,0,0,0.1)' : 'rgba(255,255,255,0.1)'};
654+
border-radius: 10px;
655+
}
656+
.sort-menu::-webkit-scrollbar-thumb {
657+
background: ${theme === 'light' ? 'rgba(0,0,0,0.3)' : 'rgba(255,255,255,0.3)'};
658+
border-radius: 10px;
659+
}
660+
.sort-menu::-webkit-scrollbar-thumb:hover {
661+
background: ${theme === 'light' ? 'rgba(0,0,0,0.5)' : 'rgba(255,255,255,0.5)'};
662+
}
639663
`
640664
}} />
641665
{filteredList.map((item, index) => (

frontend/src/components/MapComponent.jsx

Lines changed: 84 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -298,13 +298,31 @@ export default function MapComponent() {
298298
timeDifferences.push(`${diffHours}h gap`);
299299
}
300300

301-
// Create graph container
301+
// Create graph container with responsive dimensions
302302
const graphContainer = document.createElement('div');
303-
graphContainer.style.width = '600px';
304-
graphContainer.style.height = '420px';
305-
graphContainer.style.padding = '15px';
303+
graphContainer.className = 'historical-data-container';
304+
305+
// Detect mobile viewport
306+
const isMobile = window.innerWidth <= 768;
307+
const isSmallMobile = window.innerWidth <= 480;
308+
309+
// Set responsive dimensions
310+
if (isSmallMobile) {
311+
graphContainer.style.width = '340px';
312+
graphContainer.style.height = '300px';
313+
graphContainer.style.padding = '8px';
314+
} else if (isMobile) {
315+
graphContainer.style.width = '450px';
316+
graphContainer.style.height = '350px';
317+
graphContainer.style.padding = '10px';
318+
} else {
319+
graphContainer.style.width = '600px';
320+
graphContainer.style.height = '420px';
321+
graphContainer.style.padding = '15px';
322+
}
323+
306324
graphContainer.style.backgroundColor = window.globalTheme === 'dark' ? '#1a1a1a' : '#ffffff';
307-
graphContainer.style.borderRadius = '12px';
325+
graphContainer.style.borderRadius = isMobile ? '8px' : '12px';
308326
graphContainer.style.boxShadow = window.globalTheme === 'dark'
309327
? '0 8px 32px rgba(0,0,0,0.5)'
310328
: '0 8px 32px rgba(0,0,0,0.15)';
@@ -313,8 +331,18 @@ export default function MapComponent() {
313331
const canvas = document.createElement('canvas');
314332
canvas.style.width = '100%';
315333
canvas.style.height = 'calc(100% - 40px)';
316-
canvas.width = 570;
317-
canvas.height = 380;
334+
335+
// Set canvas dimensions based on screen size
336+
if (isSmallMobile) {
337+
canvas.width = 320;
338+
canvas.height = 240;
339+
} else if (isMobile) {
340+
canvas.width = 420;
341+
canvas.height = 290;
342+
} else {
343+
canvas.width = 570;
344+
canvas.height = 380;
345+
}
318346
graphContainer.appendChild(canvas);
319347

320348
console.log('Creating chart with time-based data:', timeBasedData);
@@ -346,11 +374,11 @@ export default function MapComponent() {
346374
display: true,
347375
text: `Historical Data for ${name}`,
348376
font: {
349-
size: 18,
377+
size: isSmallMobile ? 14 : (isMobile ? 16 : 18),
350378
weight: 'bold'
351379
},
352380
color: window.globalTheme === 'dark' ? '#fff' : '#333',
353-
padding: 20
381+
padding: isSmallMobile ? 10 : (isMobile ? 15 : 20)
354382
},
355383
legend: {
356384
display: false
@@ -385,26 +413,35 @@ export default function MapComponent() {
385413
type: 'linear', // Use linear instead of time to avoid adapter issues
386414
position: 'bottom',
387415
title: {
388-
display: true,
416+
display: !isSmallMobile, // Hide title on very small screens
389417
text: 'Date & Time',
390418
color: window.globalTheme === 'dark' ? '#fff' : '#333',
391419
font: {
392-
size: 14,
420+
size: isSmallMobile ? 10 : (isMobile ? 12 : 14),
393421
weight: 'bold'
394422
}
395423
},
396424
ticks: {
397425
color: window.globalTheme === 'dark' ? '#ccc' : '#666',
398-
maxRotation: 45,
426+
maxRotation: isMobile ? 45 : 45,
399427
font: {
400-
size: 10
428+
size: isSmallMobile ? 8 : (isMobile ? 9 : 10)
401429
},
402-
maxTicksLimit: 5, // Limit to prevent overcrowding
430+
maxTicksLimit: isSmallMobile ? 3 : (isMobile ? 4 : 5), // Fewer ticks on mobile
403431
callback: function(value) {
404432
// The value here is the actual timestamp (milliseconds)
405433
const date = new Date(value);
406434
if (isNaN(date.getTime())) return ''; // Invalid date
407-
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
435+
436+
// Mobile-friendly date formatting
437+
if (isSmallMobile) {
438+
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
439+
} else if (isMobile) {
440+
return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }) + '\n' +
441+
date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
442+
} else {
443+
return date.toLocaleDateString() + ' ' + date.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'});
444+
}
408445
}
409446
},
410447
grid: {
@@ -413,18 +450,18 @@ export default function MapComponent() {
413450
},
414451
y: {
415452
title: {
416-
display: true,
453+
display: !isSmallMobile, // Hide title on very small screens
417454
text: `Temperature (°${currentUnit})`,
418455
color: window.globalTheme === 'dark' ? '#fff' : '#333',
419456
font: {
420-
size: 14,
457+
size: isSmallMobile ? 10 : (isMobile ? 12 : 14),
421458
weight: 'bold'
422459
}
423460
},
424461
ticks: {
425462
color: window.globalTheme === 'dark' ? '#ccc' : '#666',
426463
font: {
427-
size: 11
464+
size: isSmallMobile ? 8 : (isMobile ? 9 : 11)
428465
},
429466
callback: function(value) {
430467
return `${value}°${currentUnit}`;
@@ -448,12 +485,14 @@ export default function MapComponent() {
448485
marker.chartData = sortedData;
449486
marker.chartContainer = graphContainer; // Store reference to the container
450487

451-
// Open popup
488+
// Open popup with responsive sizing
452489
const popup = L.popup({
453490
offset: popupOffset,
454-
maxWidth: 650,
455-
maxHeight: 470,
456-
className: 'custom-popup'
491+
maxWidth: isSmallMobile ? 360 : (isMobile ? 480 : 650),
492+
maxHeight: isSmallMobile ? 320 : (isMobile ? 370 : 470),
493+
className: 'custom-popup mobile-optimized-popup',
494+
autoPan: true,
495+
autoPanPadding: [10, 10]
457496
})
458497
.setLatLng([lat, lon])
459498
.setContent(graphContainer)
@@ -466,6 +505,25 @@ export default function MapComponent() {
466505
console.log('Chart resized');
467506
}
468507
}, 100);
508+
509+
// Add resize handler for mobile orientation changes
510+
const handleResize = () => {
511+
if (chart && chart.resize) {
512+
setTimeout(() => {
513+
chart.resize();
514+
console.log('Chart resized after orientation change');
515+
}, 200);
516+
}
517+
};
518+
519+
window.addEventListener('resize', handleResize);
520+
window.addEventListener('orientationchange', handleResize);
521+
522+
// Store cleanup function for the resize handlers
523+
marker._resizeCleanup = () => {
524+
window.removeEventListener('resize', handleResize);
525+
window.removeEventListener('orientationchange', handleResize);
526+
};
469527
});
470528

471529
// Add keyboard accessibility AFTER the click handler
@@ -574,6 +632,10 @@ export default function MapComponent() {
574632

575633
// Clear existing markers before adding new ones
576634
markersRef.current.forEach(({ marker }) => {
635+
// Clean up resize handlers if they exist
636+
if (marker._resizeCleanup) {
637+
marker._resizeCleanup();
638+
}
577639
map.removeLayer(marker);
578640
});
579641
markersRef.current = [];

frontend/src/components/TempFilterModal.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ function TempFilterModal({
224224
backgroundColor: theme === 'light' ? '#34c759' : '#30D158',
225225
border: 'none',
226226
borderRadius: '0.35rem',
227-
color: '#fff',
227+
color: 'black',
228228
cursor: 'pointer',
229229
fontSize: '0.85rem',
230230
fontWeight: '600',

frontend/src/styles/MapView.css

Lines changed: 104 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,107 @@
176176

177177
.temp-label[data-temp-category="hot"] {
178178
border-left: 4px solid #ff3b30 !important;
179-
}
179+
180+
}
181+
182+
/* Mobile-optimized popup styles */
183+
.mobile-optimized-popup .leaflet-popup-content-wrapper {
184+
border-radius: 8px !important;
185+
overflow: hidden !important;
186+
}
187+
188+
.mobile-optimized-popup .leaflet-popup-content {
189+
margin: 0 !important;
190+
padding: 0 !important;
191+
width: auto !important;
192+
height: auto !important;
193+
}
194+
195+
.historical-data-container {
196+
position: relative !important;
197+
overflow: hidden !important;
198+
box-sizing: border-box !important;
199+
}
200+
201+
/* Mobile responsive adjustments */
202+
@media (max-width: 768px) {
203+
.leaflet-popup-content-wrapper {
204+
max-width: 95vw !important;
205+
max-height: 70vh !important;
206+
}
207+
208+
.mobile-optimized-popup .leaflet-popup-content-wrapper {
209+
border-radius: 6px !important;
210+
}
211+
212+
.historical-data-container {
213+
min-height: 280px !important;
214+
}
215+
216+
217+
/* Adjust popup close button for mobile */
218+
.leaflet-popup-close-button {
219+
padding: 8px !important;
220+
font-size: 18px !important;
221+
width: 32px !important;
222+
height: 32px !important;
223+
line-height: 16px !important;
224+
}
225+
}
226+
227+
@media (max-width: 568px) {
228+
/* Move legend further up on small mobile devices */
229+
.legend {
230+
top: 36% !important;
231+
}
232+
}
233+
234+
@media (max-width: 480px) {
235+
.leaflet-popup-content-wrapper {
236+
max-width: 98vw !important;
237+
max-height: 60vh !important;
238+
}
239+
240+
.mobile-optimized-popup .leaflet-popup-content-wrapper {
241+
border-radius: 4px !important;
242+
}
243+
244+
.historical-data-container {
245+
min-height: 240px !important;
246+
}
247+
248+
249+
250+
/* Make popup close button more touch-friendly */
251+
.leaflet-popup-close-button {
252+
padding: 10px !important;
253+
font-size: 20px !important;
254+
width: 36px !important;
255+
height: 36px !important;
256+
line-height: 16px !important;
257+
background: rgba(0, 0, 0, 0.1) !important;
258+
border-radius: 50% !important;
259+
}
260+
261+
.leaflet-popup-close-button:hover {
262+
background: rgba(0, 0, 0, 0.2) !important;
263+
}
264+
}
265+
266+
/* Touch-friendly chart interactions */
267+
@media (pointer: coarse) {
268+
.historical-data-container canvas {
269+
touch-action: pan-x pan-y !important;
270+
}
271+
}
272+
273+
/* Landscape orientation adjustments for mobile */
274+
@media (max-width: 768px) and (orientation: landscape) {
275+
.historical-data-container {
276+
max-height: 50vh !important;
277+
}
278+
279+
.leaflet-popup-content-wrapper {
280+
max-height: 60vh !important;
281+
}
282+
}

0 commit comments

Comments
 (0)