From a9c46f552f1d4ff83d0ccac89e8a233a8a0b4e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rados=C5=82aw=20Gierwia=C5=82o?= Date: Sat, 29 Nov 2025 20:57:17 +0100 Subject: [PATCH] feat: add @ prefix to profile URLs and make usernames clickable - Updated all profile links to use /@username format - Made usernames clickable in chat messages - Added URL parameter sanitization to strip @ when fetching user data - Ensures consistent profile URL format across the application --- frontend/src/components/chat/ChatMessage.jsx | 8 +++++++- frontend/src/components/dashboard/DashboardMatchCard.jsx | 4 ++-- frontend/src/components/dashboard/MatchRequestCards.jsx | 8 ++++---- frontend/src/components/matches/MatchCard.jsx | 4 ++-- frontend/src/components/users/UserListItem.jsx | 2 +- frontend/src/pages/MatchChatPage.jsx | 4 ++-- frontend/src/pages/PublicProfilePage.jsx | 8 +++++--- 7 files changed, 23 insertions(+), 15 deletions(-) diff --git a/frontend/src/components/chat/ChatMessage.jsx b/frontend/src/components/chat/ChatMessage.jsx index 28429fa..a6b3207 100644 --- a/frontend/src/components/chat/ChatMessage.jsx +++ b/frontend/src/components/chat/ChatMessage.jsx @@ -1,3 +1,4 @@ +import { Link } from 'react-router-dom'; import Avatar from '../common/Avatar'; // Helper function to convert country name to flag emoji @@ -117,7 +118,12 @@ const ChatMessage = ({ message, user, participant, isOwn, formatTime }) => { {countryFlag} )} - {user.username} + + {user.username} + {participant?.competitorNumber && ( #{participant.competitorNumber} diff --git a/frontend/src/components/dashboard/DashboardMatchCard.jsx b/frontend/src/components/dashboard/DashboardMatchCard.jsx index e26f916..0ee00ea 100644 --- a/frontend/src/components/dashboard/DashboardMatchCard.jsx +++ b/frontend/src/components/dashboard/DashboardMatchCard.jsx @@ -57,7 +57,7 @@ const DashboardMatchCard = ({ match }) => {
{/* Avatar */} - + {partner.username} {
- +

{partner.firstName && partner.lastName ? `${partner.firstName} ${partner.lastName}` diff --git a/frontend/src/components/dashboard/MatchRequestCards.jsx b/frontend/src/components/dashboard/MatchRequestCards.jsx index e2db53a..f920db2 100644 --- a/frontend/src/components/dashboard/MatchRequestCards.jsx +++ b/frontend/src/components/dashboard/MatchRequestCards.jsx @@ -11,7 +11,7 @@ export const IncomingRequestCard = ({ request, onAccept, onReject, processing }) return (
- + {requester.username}
- +

{requester.firstName && requester.lastName ? `${requester.firstName} ${requester.lastName}` @@ -69,7 +69,7 @@ export const OutgoingRequestCard = ({ request, onCancel, processing }) => { return (
- + {recipient.username} {
- +

{recipient.firstName && recipient.lastName ? `${recipient.firstName} ${recipient.lastName}` diff --git a/frontend/src/components/matches/MatchCard.jsx b/frontend/src/components/matches/MatchCard.jsx index 4ca6db6..ca18f7e 100644 --- a/frontend/src/components/matches/MatchCard.jsx +++ b/frontend/src/components/matches/MatchCard.jsx @@ -16,7 +16,7 @@ const MatchCard = ({ match, onAccept, onReject, onOpenChat, processing }) => {
- + {match.partner.username} { />
- +

{match.partner.firstName && match.partner.lastName ? `${match.partner.firstName} ${match.partner.lastName}` diff --git a/frontend/src/components/users/UserListItem.jsx b/frontend/src/components/users/UserListItem.jsx index 0811ff9..025c343 100644 --- a/frontend/src/components/users/UserListItem.jsx +++ b/frontend/src/components/users/UserListItem.jsx @@ -46,7 +46,7 @@ const UserListItem = ({ const usernameContent = linkToProfile ? ( {user.username} diff --git a/frontend/src/pages/MatchChatPage.jsx b/frontend/src/pages/MatchChatPage.jsx index 2394f95..92bd4fb 100644 --- a/frontend/src/pages/MatchChatPage.jsx +++ b/frontend/src/pages/MatchChatPage.jsx @@ -219,7 +219,7 @@ const MatchChatPage = () => {
- + { />
- +

{partner.firstName && partner.lastName ? `${partner.firstName} ${partner.lastName}` diff --git a/frontend/src/pages/PublicProfilePage.jsx b/frontend/src/pages/PublicProfilePage.jsx index ab6161e..b269eba 100644 --- a/frontend/src/pages/PublicProfilePage.jsx +++ b/frontend/src/pages/PublicProfilePage.jsx @@ -6,7 +6,9 @@ import { User, MapPin, Globe, Hash, Youtube, Instagram, Facebook, Award, Users, import Avatar from '../components/common/Avatar'; const PublicProfilePage = () => { - const { username } = useParams(); + const { username: rawUsername } = useParams(); + // Strip @ from username if present (for /@username URLs) + const username = rawUsername?.startsWith('@') ? rawUsername.slice(1) : rawUsername; const [profile, setProfile] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(''); @@ -265,7 +267,7 @@ const PublicProfilePage = () => {
{/* Rater Info */} - + {
{rating.rater.firstName && rating.rater.lastName