@@ -4,11 +4,15 @@ import { hasFlag } from 'country-flag-icons';
44import getUnicodeFlagIcon from 'country-flag-icons/unicode' ;
55import { useMemo } from 'react' ;
66import { useTranslation } from 'react-i18next' ;
7+ import { Link } from 'react-router-dom' ;
78import { Button , ExternalLink , LinkButton } from '@/components' ;
89import { usePinnedPersons } from '@/hooks/UsePinnedPersons' ;
910import { useWcaLiveCompetitorLink } from '@/hooks/queries/useWcaLive' ;
1011import { useWCIF } from '@/providers/WCIFProvider' ;
1112
13+ const fallbackAvatarUrl =
14+ 'https://assets.worldcubeassociation.org/assets/326cd49/assets/missing_avatar_thumb-d77f478a307a91a9d4a083ad197012a391d5410f6dd26cb0b0e3118a5de71438.png' ;
15+
1216export interface PersonHeaderProps {
1317 competitionId ;
1418 person : Person ;
@@ -40,37 +44,55 @@ export const PersonHeader: React.FC<PersonHeaderProps> = ({ person }) => {
4044 ] ;
4145 } , [ person . registration ?. eventIds , person . roles ] ) ;
4246
47+ const avatarUrl = person ?. avatar ?. thumbUrl || person ?. avatar ?. url || fallbackAvatarUrl ;
48+
49+ const avatar = < img src = { avatarUrl } alt = { person . name } className = "w-24 h-24 object-contain" /> ;
50+
4351 return (
4452 < >
45- < div className = "flex flex-shrink items-center w-full space-x-1 min-h-10 px-1" >
46- { hasFlag ( person . countryIso2 ) && (
47- < div className = "flex flex-shrink text-lg sm:text-xl mx-1" >
48- { getUnicodeFlagIcon ( person . countryIso2 ) }
49- </ div >
53+ < div className = "flex space-x-1 px-1" >
54+ { person . wcaId ? (
55+ < Link to = { `https://worldcubeassociation.org/persons/${ person . wcaId } ` } target = "_blank" >
56+ { avatar }
57+ </ Link >
58+ ) : (
59+ avatar
5060 ) }
51- < h3 className = "text-xl sm:text-2xl" > { person . name } </ h3 >
52- < div className = "flex-grow" />
53- < span className = "text-xl sm:text-2xl" > { person . registrantId } </ span >
54- < Button
55- className = "bg-blue-200"
56- onClick = { ( ) => {
57- if ( isPinned ) {
58- unpinPerson ( person . registrantId ) ;
59- } else {
60- pinPerson ( person . registrantId ) ;
61- }
62- } } >
63- < PinIcon pinned = { isPinned } />
64- </ Button >
65- </ div >
66- { person . wcaId && < span className = "px-1" > { person . wcaId } </ span > }
67- < div className = "px-1" >
68- < p className = "text-sm sm:text-md" >
69- < span > { t ( 'competition.personalSchedule.registeredEvents' ) } :</ span >
70- { registeredEventIconClassNames . map ( ( eventId ) => (
71- < span key = { eventId } className = { classNames ( `cubing-icon ${ eventId } mx-1 text-lg` ) } />
72- ) ) }
73- </ p >
61+ < div className = "flex flex-col w-full" >
62+ < div className = "flex flex-shrink items-center w-full space-x-1" >
63+ < h3 className = "text-xl sm:text-2xl" > { person . name } </ h3 >
64+ < div className = "flex-grow" />
65+ < span className = "text-xl sm:text-2xl" > { person . registrantId } </ span >
66+ < Button
67+ className = "bg-blue-200 min-h-10"
68+ onClick = { ( ) => {
69+ if ( isPinned ) {
70+ unpinPerson ( person . registrantId ) ;
71+ } else {
72+ pinPerson ( person . registrantId ) ;
73+ }
74+ } } >
75+ < PinIcon pinned = { isPinned } />
76+ </ Button >
77+ </ div >
78+ < div className = "flex space-x-1 align-center" >
79+ { hasFlag ( person . countryIso2 ) && (
80+ < div className = "flex flex-shrink text-lg sm:text-xl" >
81+ { getUnicodeFlagIcon ( person . countryIso2 ) }
82+ </ div >
83+ ) }
84+
85+ { person . wcaId && < span className = "text-sm sm:text-md my-1" > { person . wcaId } </ span > }
86+ </ div >
87+ < div className = "px-1" >
88+ < p className = "text-sm sm:text-md" >
89+ < span > { t ( 'competition.personalSchedule.registeredEvents' ) } :</ span >
90+ { registeredEventIconClassNames . map ( ( eventId ) => (
91+ < span key = { eventId } className = { classNames ( `cubing-icon ${ eventId } mx-1 text-lg` ) } />
92+ ) ) }
93+ </ p >
94+ </ div >
95+ </ div >
7496 </ div >
7597 { person . wcaId && (
7698 < >
0 commit comments