From 3d1817618d83b519c865a2c5c92ecb574ca6fbd1 Mon Sep 17 00:00:00 2001 From: George Kargiotakis Date: Sun, 7 Jun 2026 15:57:15 +0300 Subject: [PATCH 1/2] Optimize mobile listings and depth iconography Remove text descriptions from dive site and diving center listing views on mobile viewports to increase data density, save screen real estate, and prevent scrolling fatigue. Introduce a custom thematic 'DepthIcon' component portraying an ocean waves boundary and a downward-pointing arrow to semantically represent all water depth metrics. Standardize this icon across dive cards, grids, maps, and profile charts. Unify the contact buttons (Website, Email, and Phone) inside diving center cards using the official 'text-divemap-blue' brand color and a consistent subtle background tint. This streamlines the action palette and reduces visual complexity. --- .../components/AdvancedDiveProfileChart.jsx | 9 +++-- frontend/src/components/DiveInfoGrid.jsx | 9 ++--- frontend/src/components/DiveSiteCard.jsx | 15 ++++---- frontend/src/components/DivesMap.jsx | 5 +-- frontend/src/components/LeafletMapView.jsx | 7 ++-- frontend/src/components/TripCard.jsx | 4 +-- .../src/components/UserChat/MessageBubble.jsx | 5 +-- frontend/src/components/ui/DepthIcon.jsx | 34 +++++++++++++++++++ frontend/src/pages/DivingCenters.jsx | 30 ++++++++-------- 9 files changed, 79 insertions(+), 39 deletions(-) create mode 100644 frontend/src/components/ui/DepthIcon.jsx diff --git a/frontend/src/components/AdvancedDiveProfileChart.jsx b/frontend/src/components/AdvancedDiveProfileChart.jsx index f3c118d..8bc62a0 100644 --- a/frontend/src/components/AdvancedDiveProfileChart.jsx +++ b/frontend/src/components/AdvancedDiveProfileChart.jsx @@ -11,7 +11,6 @@ import { X, Contrast, Upload, - TrendingUp, Loader2, Wind, } from 'lucide-react'; @@ -34,6 +33,8 @@ import api from '../api'; import { useResponsive } from '../hooks/useResponsive'; import { formatGases } from '../utils/textHelpers'; +import DepthIcon from './ui/DepthIcon'; + /** * Custom Tooltip component for the chart */ @@ -713,9 +714,7 @@ const AdvancedDiveProfileChart = ({
- + @@ -723,7 +722,7 @@ const AdvancedDiveProfileChart = ({
- + diff --git a/frontend/src/components/DiveInfoGrid.jsx b/frontend/src/components/DiveInfoGrid.jsx index 04e743e..4f1a8d0 100644 --- a/frontend/src/components/DiveInfoGrid.jsx +++ b/frontend/src/components/DiveInfoGrid.jsx @@ -1,11 +1,12 @@ import { Row, Col } from 'antd'; import { Grid } from 'antd-mobile'; -import { Calendar, Clock, Eye, TrendingUp, User, Notebook, Wind, Droplets } from 'lucide-react'; +import { Calendar, Clock, Eye, User, Notebook, Wind, Droplets } from 'lucide-react'; import React from 'react'; import { getTagColor } from '../utils/tagHelpers'; import { formatGases } from '../utils/textHelpers'; +import DepthIcon from './ui/DepthIcon'; import DifficultyBadge from './ui/DifficultyBadge'; const DiveInfoGrid = ({ dive, hasDeco, isMobile, formatDate, formatTime }) => { @@ -122,7 +123,7 @@ const DiveInfoGrid = ({ dive, hasDeco, isMobile, formatDate, formatTime }) => { Max Depth
- + {dive.max_depth || '-'} m @@ -257,7 +258,7 @@ const DiveInfoGrid = ({ dive, hasDeco, isMobile, formatDate, formatTime }) => { Max Depth
- + {dive.max_depth || '-'} m @@ -349,7 +350,7 @@ const DiveInfoGrid = ({ dive, hasDeco, isMobile, formatDate, formatTime }) => { {dive.average_depth && (
- + Avg Depth: {dive.average_depth}m
diff --git a/frontend/src/components/DiveSiteCard.jsx b/frontend/src/components/DiveSiteCard.jsx index 3d460bb..499f6fb 100644 --- a/frontend/src/components/DiveSiteCard.jsx +++ b/frontend/src/components/DiveSiteCard.jsx @@ -1,4 +1,4 @@ -import { Globe, User, TrendingUp, Fish, ChevronRight, Route } from 'lucide-react'; +import { Globe, User, Fish, ChevronRight, Route } from 'lucide-react'; import React from 'react'; import { Link } from 'react-router-dom'; @@ -8,6 +8,7 @@ import { slugify, getDiveSiteSlug } from '../utils/slugify'; import { getTagColor } from '../utils/tagHelpers'; import { renderTextWithLinks } from '../utils/textHelpers'; +import DepthIcon from './ui/DepthIcon'; import DifficultyBadge from './ui/DifficultyBadge'; export const DiveSiteListCard = ({ @@ -79,8 +80,8 @@ export const DiveSiteListCard = ({ {/* Content Row: Description, Stats and Mobile Thumbnail */}
- {/* BODY: Description - More aggressive clamp on mobile */} - {site.description && ( + {/* BODY: Description - Completely removed on mobile view */} + {!isMobile && site.description && (
@@ -95,7 +96,7 @@ export const DiveSiteListCard = ({
{site.max_depth && (
- + {site.max_depth}m @@ -167,6 +168,8 @@ export const DiveSiteGridCard = ({ getThumbnailUrl, handleFilterChange, }) => { + const { isMobile } = useResponsive(); + return (
{site.max_depth && (
- + {site.max_depth}m
)} @@ -240,7 +243,7 @@ export const DiveSiteGridCard = ({
{/* Description */} - {site.description && ( + {!isMobile && site.description && (

{decodeHtmlEntities(site.description)}

diff --git a/frontend/src/components/DivesMap.jsx b/frontend/src/components/DivesMap.jsx index e3e947c..6eb54cd 100644 --- a/frontend/src/components/DivesMap.jsx +++ b/frontend/src/components/DivesMap.jsx @@ -1,7 +1,7 @@ import DOMPurify from 'dompurify'; import L, { Icon } from 'leaflet'; import escape from 'lodash/escape'; -import { Calendar, Clock, TrendingUp, Star } from 'lucide-react'; +import { Calendar, Clock, Star } from 'lucide-react'; import 'leaflet/dist/leaflet.css'; import 'leaflet.markercluster/dist/MarkerCluster.css'; import 'leaflet.markercluster'; @@ -14,6 +14,7 @@ import { formatDate, formatTime } from '../utils/dateHelpers'; import { getDifficultyLabel, getDifficultyColorClasses } from '../utils/difficultyHelpers'; import { slugify } from '../utils/slugify'; +import DepthIcon from './ui/DepthIcon'; import DifficultyBadge from './ui/DifficultyBadge'; // Fix default marker icons @@ -373,7 +374,7 @@ const DivesMap = ({ dives = [], onViewportChange }) => {
{dive.max_depth && (
- + {dive.max_depth}m max
)} diff --git a/frontend/src/components/LeafletMapView.jsx b/frontend/src/components/LeafletMapView.jsx index 2981af1..d358542 100644 --- a/frontend/src/components/LeafletMapView.jsx +++ b/frontend/src/components/LeafletMapView.jsx @@ -1,7 +1,7 @@ import DOMPurify from 'dompurify'; import L, { Icon } from 'leaflet'; import escape from 'lodash/escape'; -import { Info, Phone, Mail, Globe, TrendingUp, TrendingDown, Clock } from 'lucide-react'; +import { Info, Phone, Mail, Globe, Clock } from 'lucide-react'; import React, { useMemo, useCallback, useEffect, useRef, useState } from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; import { MapContainer, TileLayer, Marker, Popup, useMap } from 'react-leaflet'; @@ -21,6 +21,7 @@ import { formatWindDirection, } from '../utils/windSuitabilityHelpers'; +import DepthIcon from './ui/DepthIcon'; import WindDataError from './WindDataError'; import WindOverlay from './WindOverlay'; import WindOverlayLegend from './WindOverlayLegend'; @@ -31,8 +32,8 @@ const ICONS = { Phone: renderToStaticMarkup(), Mail: renderToStaticMarkup(), Globe: renderToStaticMarkup(), - AverageDepth: renderToStaticMarkup(), - MaxDepth: renderToStaticMarkup(), + AverageDepth: renderToStaticMarkup(), + MaxDepth: renderToStaticMarkup(), Duration: renderToStaticMarkup(), }; diff --git a/frontend/src/components/TripCard.jsx b/frontend/src/components/TripCard.jsx index d3b81c9..f34e03a 100644 --- a/frontend/src/components/TripCard.jsx +++ b/frontend/src/components/TripCard.jsx @@ -3,7 +3,6 @@ import { Clock, Euro, Users, - TrendingUp, MapPin, Building, Edit, @@ -21,6 +20,7 @@ import { slugify, getDiveSiteSlug, getDivingCenterSlug } from '../utils/slugify' import { getStatusColorClasses, getDisplayStatus } from '../utils/tripHelpers'; import { generateTripName } from '../utils/tripNameGenerator'; +import DepthIcon from './ui/DepthIcon'; import DifficultyBadge from './ui/DifficultyBadge'; /** @@ -323,7 +323,7 @@ const TripCard = ({ )} {trip.max_depth ? (
- +
Max Depth diff --git a/frontend/src/components/UserChat/MessageBubble.jsx b/frontend/src/components/UserChat/MessageBubble.jsx index b062eae..649e114 100644 --- a/frontend/src/components/UserChat/MessageBubble.jsx +++ b/frontend/src/components/UserChat/MessageBubble.jsx @@ -1,5 +1,5 @@ import { format } from 'date-fns'; -import { Edit2, Check, CheckCheck, Clock, MapPin, TrendingUp } from 'lucide-react'; +import { Edit2, Check, CheckCheck, Clock, MapPin } from 'lucide-react'; import PropTypes from 'prop-types'; import React, { useMemo } from 'react'; import ReactMarkdown from 'react-markdown'; @@ -11,6 +11,7 @@ import { slugify, getDiveSiteSlug } from '../../utils/slugify'; import Avatar from '../Avatar'; import ChatbotIcon from '../Chat/ChatbotIcon.jsx'; import CurrencyIcon from '../ui/CurrencyIcon'; +import DepthIcon from '../ui/DepthIcon'; import LinkPreview from './LinkPreview'; @@ -239,7 +240,7 @@ const MessageBubble = ({ )} {tripData.max_depth && (
- + {tripData.max_depth}m diff --git a/frontend/src/components/ui/DepthIcon.jsx b/frontend/src/components/ui/DepthIcon.jsx new file mode 100644 index 0000000..ce88047 --- /dev/null +++ b/frontend/src/components/ui/DepthIcon.jsx @@ -0,0 +1,34 @@ +import PropTypes from 'prop-types'; +import React from 'react'; + +const DepthIcon = ({ className = '', size = 16, strokeWidth = 2.5, ...props }) => { + return ( + + {/* Ocean waves at the top */} + + {/* Vertical descending line */} + + {/* Downward pointing arrowhead */} + + + ); +}; + +DepthIcon.propTypes = { + className: PropTypes.string, + size: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + strokeWidth: PropTypes.number, +}; + +export default DepthIcon; diff --git a/frontend/src/pages/DivingCenters.jsx b/frontend/src/pages/DivingCenters.jsx index 97099e2..811f486 100644 --- a/frontend/src/pages/DivingCenters.jsx +++ b/frontend/src/pages/DivingCenters.jsx @@ -488,9 +488,9 @@ const DivingCenters = () => { )}
- {/* Description - expanded to fill space */} - {center.description && ( -

+ {/* Description - completely removed on mobile view */} + {!isMobile && center.description && ( +

{decodeHtmlEntities(center.description)}

)} @@ -507,37 +507,37 @@ const DivingCenters = () => { } target='_blank' rel='noopener noreferrer' - className='w-8 h-8 inline-flex items-center justify-center bg-blue-100 text-blue-700 rounded-lg hover:bg-blue-200 active:scale-95 transition-all' + className='w-8 h-8 inline-flex items-center justify-center bg-blue-50 text-divemap-blue rounded-lg hover:bg-blue-100/70 active:scale-95 transition-all' title='Website' > - + )} {center.email && (isMobile ? ( - + ) : ( - + ))} {center.phone && ( - + )} { )}
- {/* Description */} - {center.description && ( + {/* Description - completely removed on mobile view */} + {!isMobile && center.description && (

{decodeHtmlEntities(center.description)}

@@ -625,7 +625,7 @@ const DivingCenters = () => { {center.phone && ( @@ -640,7 +640,7 @@ const DivingCenters = () => { } target='_blank' rel='noopener noreferrer' - className='p-2 bg-gray-50 text-gray-600 rounded-lg hover:bg-gray-100 transition-colors' + className='p-2 bg-blue-50 text-divemap-blue rounded-lg hover:bg-blue-100/70 active:scale-95 transition-all' title='Website' > From 339b0841150b5d8737de59bf60a689b633042cc0 Mon Sep 17 00:00:00 2001 From: George Kargiotakis Date: Mon, 8 Jun 2026 10:41:46 +0300 Subject: [PATCH 2/2] Standardize depth icons across remaining pages Replace remaining occurrences of 'TrendingUp' and 'TrendingDown' with the custom thematic 'DepthIcon' component in log, site detail, trip detail, and user profile views. This guarantees global visual consistency for all water depth metrics. Additionally, remove unused 'TrendingUp' imports from list pages such as 'DiveSites.jsx' and 'DiveTrips.jsx' to clean up dead code. --- frontend/src/pages/DiveSiteDetail.jsx | 5 +++-- frontend/src/pages/DiveSites.jsx | 1 - frontend/src/pages/DiveTrips.jsx | 1 - frontend/src/pages/Dives.jsx | 6 +++--- frontend/src/pages/Profile.jsx | 5 +++-- frontend/src/pages/TripDetail.jsx | 4 ++-- frontend/src/pages/UserProfile.jsx | 11 +++++------ 7 files changed, 16 insertions(+), 17 deletions(-) diff --git a/frontend/src/pages/DiveSiteDetail.jsx b/frontend/src/pages/DiveSiteDetail.jsx index 82cf07b..77d0fb9 100644 --- a/frontend/src/pages/DiveSiteDetail.jsx +++ b/frontend/src/pages/DiveSiteDetail.jsx @@ -54,6 +54,7 @@ import SEO from '../components/SEO'; import ShareButton from '../components/ShareButton'; import StickyRateBar from '../components/StickyRateBar'; import Button from '../components/ui/Button'; +import DepthIcon from '../components/ui/DepthIcon'; import DifficultyBadge from '../components/ui/DifficultyBadge'; import RichText from '../components/ui/RichText'; import StarfishRating from '../components/ui/StarfishRating'; @@ -582,7 +583,7 @@ const DiveSiteDetail = () => {
{dive.max_depth && (
- + {dive.max_depth}m
)} @@ -874,7 +875,7 @@ const DiveSiteDetail = () => { Max Depth
- + {diveSite.max_depth} m diff --git a/frontend/src/pages/DiveSites.jsx b/frontend/src/pages/DiveSites.jsx index ab9790f..e1ca2c1 100644 --- a/frontend/src/pages/DiveSites.jsx +++ b/frontend/src/pages/DiveSites.jsx @@ -7,7 +7,6 @@ import { ChevronRight, Star, MapPin, - TrendingUp, Compass, Globe, List, diff --git a/frontend/src/pages/DiveTrips.jsx b/frontend/src/pages/DiveTrips.jsx index 0f62c01..0fe6808 100644 --- a/frontend/src/pages/DiveTrips.jsx +++ b/frontend/src/pages/DiveTrips.jsx @@ -14,7 +14,6 @@ import { Tag, List, Grid, - TrendingUp, DollarSign, Star, ChevronDown, diff --git a/frontend/src/pages/Dives.jsx b/frontend/src/pages/Dives.jsx index 7d4eee4..f8dcdfd 100644 --- a/frontend/src/pages/Dives.jsx +++ b/frontend/src/pages/Dives.jsx @@ -15,7 +15,6 @@ import { Filter, Upload, Calendar, - TrendingUp, Grid, Route, User, @@ -44,6 +43,7 @@ import PageHeader from '../components/PageHeader'; import RateLimitError from '../components/RateLimitError'; import ResponsiveFilterBar from '../components/ResponsiveFilterBar'; import SEO from '../components/SEO'; +import DepthIcon from '../components/ui/DepthIcon'; import DifficultyBadge from '../components/ui/DifficultyBadge'; import InfiniteScrollTrigger from '../components/ui/InfiniteScrollTrigger'; import { useAuth } from '../contexts/AuthContext'; @@ -946,7 +946,7 @@ const Dives = () => {
{dive.max_depth && (
- + {dive.max_depth}m @@ -1075,7 +1075,7 @@ const Dives = () => { {/* Stats Grid (Simplified for Grid layout) */}
- +

Depth diff --git a/frontend/src/pages/Profile.jsx b/frontend/src/pages/Profile.jsx index 2c3746e..6c94937 100644 --- a/frontend/src/pages/Profile.jsx +++ b/frontend/src/pages/Profile.jsx @@ -45,6 +45,7 @@ import OrganizationLogo from '../components/OrganizationLogo'; import SEO from '../components/SEO'; import { getSocialMediaIcon } from '../components/SocialMediaIcons'; import Button from '../components/ui/Button'; +import DepthIcon from '../components/ui/DepthIcon'; import { useAuth } from '../contexts/AuthContext'; import { getDivingCenters } from '../services/divingCenters'; import { getFullAvatarUrl } from '../utils/avatarHelpers'; @@ -423,10 +424,10 @@ const Profile = () => { } features.push({ - icon: , + icon: , label: shortDepth, title: `Max Depth: ${max_depth}`, - color: 'bg-blue-50 text-blue-700 border-blue-100', + color: 'bg-blue-50 text-divemap-blue border-blue-100', }); } diff --git a/frontend/src/pages/TripDetail.jsx b/frontend/src/pages/TripDetail.jsx index ad3eb33..437d6a4 100644 --- a/frontend/src/pages/TripDetail.jsx +++ b/frontend/src/pages/TripDetail.jsx @@ -9,7 +9,6 @@ import { Building, Ticket, LogIn, - TrendingUp, Edit, X, Upload, @@ -27,6 +26,7 @@ import SEO from '../components/SEO'; import TripFormModal from '../components/TripFormModal'; import TripHeader from '../components/TripHeader'; import Button from '../components/ui/Button'; +import DepthIcon from '../components/ui/DepthIcon'; import RichText from '../components/ui/RichText'; import { useAuth } from '../contexts/AuthContext'; import { useSetting } from '../hooks/useSettings'; @@ -115,7 +115,7 @@ const DiveSiteInfo = ({ dive, index }) => { )}

- + {diveSite?.max_depth ? `${diveSite.max_depth}m max` : 'Depth TBD'}
diff --git a/frontend/src/pages/UserProfile.jsx b/frontend/src/pages/UserProfile.jsx index 272a28c..e126697 100644 --- a/frontend/src/pages/UserProfile.jsx +++ b/frontend/src/pages/UserProfile.jsx @@ -55,6 +55,7 @@ import Avatar from '../components/Avatar'; import OrganizationLogo from '../components/OrganizationLogo'; import SEO from '../components/SEO'; import { getSocialMediaIcon } from '../components/SocialMediaIcons'; +import DepthIcon from '../components/ui/DepthIcon'; import { useAuth } from '../contexts/AuthContext'; import { formatDate } from '../utils/dateHelpers'; import { formatGases } from '../utils/textHelpers'; @@ -303,10 +304,10 @@ const UserProfile = () => { } features.push({ - icon: , + icon: , label: shortDepth, title: `Max Depth: ${max_depth}`, - color: 'bg-blue-50 text-blue-700 border-blue-100', + color: 'bg-blue-50 text-divemap-blue border-blue-100', }); } @@ -470,9 +471,7 @@ const UserProfile = () => { > {stats.max_depth_str && ( - } + icon={} value={stats.max_depth_str} label='Max Depth' color='blue' @@ -885,7 +884,7 @@ const UserProfile = () => { value={profile.diving_stats.max_depth || 0} suffix={m} precision={1} - prefix={} + prefix={} styles={{ content: { fontSize: '18px', fontWeight: 'bold' } }} />