@@ -16,16 +16,29 @@ import Loading from './Loading'
1616import { searchableProperties } from '@/app/services/searchableProperties.js'
1717import SearchIcon from '@/public/search'
1818
19+ const cleanTeamName = ( teamName ) => {
20+ return teamName ? teamName . replace ( / \s * \( [ M m W w ] \) \s * $ / , '' ) . trim ( ) : teamName
21+ }
22+
23+ const getUniqueMatches = ( matches , cleanTeamName ) => {
24+ const uniqueKeys = new Set ( )
25+ return matches . filter ( ( match ) => {
26+ const cleanedOpponentTeam = cleanTeamName ( match . teams . opponentTeam )
27+ let matchKey = `${ match . matchDate } #${ cleanedOpponentTeam } `
28+ if ( ! match . matchDetails . duel ) matchKey = `_#${ match . matchDetails . event } `
29+
30+ if ( uniqueKeys . has ( matchKey ) ) return false
31+ uniqueKeys . add ( matchKey )
32+ return true
33+ } )
34+ }
35+
1936const formatMatches = ( matches ) => {
2037 return matches
2138 . filter ( ( match ) => match . version === 'v1' )
2239 . sort ( ( a , b ) => new Date ( b . matchDate ) - new Date ( a . matchDate ) )
2340}
2441
25- const cleanTeamName = ( teamName ) => {
26- return teamName ? teamName . replace ( / \s + \( [ M W ] \) $ / , '' ) : teamName
27- }
28-
2942// Memoized CarouselItem with fixed dimensions but original logo container
3043const CarouselItem = React . memo ( ( { match, isSelected, onClick, logo } ) => {
3144 const matchKey = match . matchDetails . duel
@@ -230,6 +243,11 @@ const Dashboard = () => {
230243 return formatted
231244 } , [ matches , isLoaded ] )
232245
246+ const uniqueMatches = useMemo (
247+ ( ) => getUniqueMatches ( formattedMatches , cleanTeamName ) ,
248+ [ formattedMatches ]
249+ )
250+
233251 // Mobile detection useEffect
234252 useEffect ( ( ) => {
235253 const checkIfMobile = ( ) => setIsMobile ( window . innerWidth < 400 )
@@ -295,20 +313,6 @@ const Dashboard = () => {
295313 ]
296314 } , [ searchTerm , filteredMatchSets , selectedMatchSets , formattedMatches ] )
297315
298- // Get unique matches for carousel (avoiding duplicates)
299- const uniqueCarouselMatches = useMemo ( ( ) => {
300- const uniqueKeys = new Set ( )
301- return formattedMatches . filter ( ( match ) => {
302- const matchKey = match . matchDetails . duel
303- ? `${ match . matchDate } #${ match . teams . opponentTeam } `
304- : `_#${ match . matchDetails . event } `
305-
306- if ( uniqueKeys . has ( matchKey ) ) return false
307- uniqueKeys . add ( matchKey )
308- return true
309- } )
310- } , [ formattedMatches ] )
311-
312316 const handleTileClick = useCallback (
313317 ( videoId ) => {
314318 router . push ( `/matches/${ videoId } ` )
@@ -345,24 +349,22 @@ const Dashboard = () => {
345349
346350 < div className = { styles . carousel } >
347351 { ! formattedMatches . length
348- ? // Placeholder skeletons for carousel items
349- Array ( 10 )
352+ ? Array ( 10 )
350353 . fill ( 0 )
351354 . map ( ( _ , i ) => (
352355 < div
353356 key = { i }
354357 className = { `${ styles . card } ${ styles . placeholderCard } ` }
355358 />
356359 ) )
357- : // Map over unique carousel matches to render each CarouselItem
358- uniqueCarouselMatches . map ( ( match , index ) => {
360+ : uniqueMatches . map ( ( match ) => {
359361 const matchKey = match . matchDetails . duel
360362 ? `${ match . matchDate } #${ match . teams . opponentTeam } `
361363 : `_#${ match . matchDetails . event } `
362364
363365 return (
364366 < CarouselItem
365- key = { index }
367+ key = { matchKey }
366368 match = { match }
367369 logo = { logos [ match . teams . opponentTeam ] }
368370 isSelected = { selectedMatchSets . includes ( matchKey ) }
0 commit comments