8.9 KiB
Matches Page Enhancements
Overview
Enhanced the Matches page (MatchesPage.tsx) with sorting functionality, improved date handling, countdown display, enhanced status badges, Czech date formatting, and "Všechny kategorie" tab showing all matches.
Changes Made
1. Sort Functionality
- ✅ Added date sorting: oldest to newest by default
- ✅ Added toggle button at the top to switch between:
- "Nejstarší první" (Oldest first) - ascending order
- "Nejnovější první" (Newest first) - descending order
- ✅ Visual indicator (icon) shows current sort direction
- ✅ Smooth transitions and hover effects on the sort button
2. Enhanced Date Handling
- ✅ Improved date comparison logic using
Date.now()consistently - ✅ Added explicit
currentTimevariable for accurate comparisons - ✅ Fixed future/past match detection
- ✅ Better handling of match states: future, past, and finished
3. Countdown Display
- ✅ Countdown automatically shows for upcoming matches
- ✅ Updates every 30 seconds (configurable)
- ✅ Format: "Začátek za" + countdown time
- ✅ Shows days/hours, hours/minutes, or minutes based on time remaining
- ✅ Orange color (#f97316) for visual emphasis
4. Enhanced Status Badges
All status badges now feature:
- Gradient backgrounds
- Better visual hierarchy
- Consistent padding and styling
- Box shadows for depth
Status Types:
-
✓ Skončeno (Finished) - Green gradient
- Shown when match has a score
linear-gradient(135deg, #10b981 0%, #059669 100%)
-
Odehráno (Played) - Gray gradient
- NEW: Shows for past matches without scores
linear-gradient(135deg, #6b7280 0%, #4b5563 100%)
-
Nadcházející (Upcoming) - Blue gradient
- Shown for future matches without countdown
linear-gradient(135deg, #3b82f6 0%, #2563eb 100%)
5. Czech Date Formatting
- ✅ Dates now display in Czech format: DD.MM.YYYY
- ✅ Uses
toLocaleDateString('cs-CZ')for proper localization - ✅ Consistent date formatting across all match cards
6. "Všechny kategorie" Tab
- ✅ NEW: Added as the first tab
- ✅ Shows all matches from all competitions combined
- ✅ Matches sorted by date (respects sort order setting)
- ✅ Each match shows its competition name below the venue
- ✅ Automatically updates when competitions load
7. Smart Match Score Handling
- ✅ CRITICAL FIX: Future matches no longer show score even if API data exists
- ✅ Checks match timestamp against current time during data loading
- ✅ Sets score to
nullONLY for future matches - ✅ Past matches keep their scores from the API
- ✅ Ensures countdown always displays for upcoming matches instead of bogus scores
8. Code Improvements
- Added
sortAscendingstate to track sort order - Created
sortedCompetitionsmemoized value for efficient sorting - Added
formatCzechDate()helper function - Removed inline sort logic from data fetching
- Better separation of concerns
- Improved performance with useMemo
- Added location emoji (📍) to venue display
Technical Details
Key State Changes
const [sortAscending, setSortAscending] = useState<boolean>(true); // true = oldest first
Sorting Logic
const sortedCompetitions = useMemo(() => {
return facrCompetitions.map(comp => ({
...comp,
matches: [...comp.matches].sort((a: any, b: any) => {
const aTime = new Date(`${a.date}T${(a.time || '00:00')}:00`).getTime();
const bTime = new Date(`${b.date}T${(b.time || '00:00')}:00`).getTime();
return sortAscending ? aTime - bTime : bTime - aTime;
})
}));
}, [facrCompetitions, sortAscending]);
Match State Detection
const matchTime = new Date(`${m.date}T${(m.time || '00:00')}:00`).getTime();
const currentTime = Date.now();
const isFuture = matchTime > currentTime;
const isPast = matchTime < currentTime;
const hasScore = m.score && m.score.trim() !== '';
Smart Score Handling (Future vs Past)
// In data loading - prevent ONLY future matches from showing scores
const matchTime = new Date(`${isoDate}T${time}:00`).getTime();
const isFutureMatch = matchTime > Date.now();
const actualScore = isFutureMatch ? null : m.score;
// Logic breakdown:
// - If match is in FUTURE → set score to null (show countdown instead)
// - If match is in PAST → keep score from API (show actual result)
Czech Date Formatting
const formatCzechDate = (dateStr: string, timeStr: string) => {
try {
const date = new Date(`${dateStr}T${timeStr}:00`);
return date.toLocaleDateString('cs-CZ', {
day: 'numeric',
month: 'numeric',
year: 'numeric'
});
} catch {
return dateStr;
}
};
All Categories Tab
// Add "Všechny kategorie" as first tab with all matches combined
if (sorted.length > 0) {
const allMatches = sorted.flatMap(comp =>
comp.matches.map(m => ({ ...m, competitionName: comp.name }))
);
allMatches.sort((a: any, b: any) => {
const aTime = new Date(`${a.date}T${(a.time || '00:00')}:00`).getTime();
const bTime = new Date(`${b.date}T${(b.time || '00:00')}:00`).getTime();
return sortAscending ? aTime - bTime : bTime - aTime;
});
return [
{
name: 'Všechny kategorie',
matches: allMatches,
matches_link: undefined
},
...sorted
];
}
User Interface
Sort Button
- Located at the top right, next to the page title
- Shows icon indicating current sort direction
- Smooth hover animation
- Uses primary brand color
- Responsive design
Match Cards
Each match card now displays:
- Date and time at the top (Czech format: DD.MM.YYYY)
- Home team logo and name
- Score OR countdown (for upcoming matches - prioritizes countdown)
- Away team logo and name
- Venue with location emoji 📍 (if available)
- Competition name (only on "Všechny kategorie" tab)
- Status badge at the bottom
Testing Recommendations
-
"Všechny kategorie" Tab
- Verify it appears as the first tab
- Check all matches from all competitions are shown
- Confirm competition names appear below venue
- Test sorting works on this tab
-
Sort Functionality
- Click the sort button and verify order changes
- Check that all tabs maintain their individual sort order
- Verify icon changes with sort direction
-
Future Match Handling ⚠️ CRITICAL
- Test with future matches that have score data
- Verify countdown displays instead of score
- Confirm "Nadcházející" status shows
- Example: Match on 10/12/2025 should show countdown, NOT 0:0 score
-
Countdown Display
- Check upcoming matches show countdown
- Verify countdown updates (wait 30 seconds)
- Test with matches at different time ranges (days, hours, minutes)
-
Czech Date Format
- Verify dates display as DD.MM.YYYY (e.g., 12.10.2025)
- Check consistency across all match cards
-
Status Badges
- Verify finished matches show "✓ Skončeno"
- Check past matches without scores show "Odehráno"
- Confirm future matches show "Nadcházející"
-
Date Accuracy
- Verify matches transition from future to past correctly
- Check timezone handling
- Test with matches around midnight
Browser Compatibility
- Modern browsers (Chrome, Firefox, Safari, Edge)
- Uses standard JavaScript Date API
- CSS gradients supported in all modern browsers
- SVG icons for sort button
Performance
- Sorting is memoized to prevent unnecessary recalculations
- Countdown updates optimized to 30-second intervals
- No performance impact on large match lists
Bug Fixes
Critical Bug Fixed: Future Matches Showing Score
Problem: Matches scheduled in the future (e.g., 10/12/2025 at 15:00) were displaying scores (e.g., 0:0) and "Skončeno" status even though they hadn't been played yet.
Root Cause: Score data from API was being displayed without checking if the match had actually occurred.
Solution:
- Added time check during data loading:
matchTime > Date.now() - Set score to
nullONLY for matches in the future - Past matches keep their actual scores from the API
- Changed display logic to prioritize countdown for future matches
- Now correctly shows countdown and "Nadcházející" status for future matches
- Past matches correctly show their scores and "✓ Skončeno" status
Important: This fix does NOT remove scores from past matches - it only prevents future matches from showing scores they shouldn't have yet.
Future Enhancements
Potential improvements:
- Add filter by date range
- Add search functionality
- Add competition-specific sorting preferences
- Export matches to calendar
- Share individual match cards
- Add match notifications/reminders
Date: 2025-10-11 (Updated: 15:54)
File Modified: frontend/src/pages/MatchesPage.tsx
Status: ✅ Complete
Critical Fix: ✅ Future match countdown issue resolved