mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 02:32:57 +00:00
upload
This commit is contained in:
@@ -0,0 +1,261 @@
|
||||
# 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 `currentTime` variable 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:**
|
||||
1. **✓ Skončeno** (Finished) - Green gradient
|
||||
- Shown when match has a score
|
||||
- `linear-gradient(135deg, #10b981 0%, #059669 100%)`
|
||||
|
||||
2. **Odehráno** (Played) - Gray gradient
|
||||
- NEW: Shows for past matches without scores
|
||||
- `linear-gradient(135deg, #6b7280 0%, #4b5563 100%)`
|
||||
|
||||
3. **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 `null` **ONLY 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 `sortAscending` state to track sort order
|
||||
- Created `sortedCompetitions` memoized 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
|
||||
```typescript
|
||||
const [sortAscending, setSortAscending] = useState<boolean>(true); // true = oldest first
|
||||
```
|
||||
|
||||
### Sorting Logic
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
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)
|
||||
```typescript
|
||||
// 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
|
||||
```typescript
|
||||
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
|
||||
```typescript
|
||||
// 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:
|
||||
1. **Date and time** at the top (Czech format: DD.MM.YYYY)
|
||||
2. **Home team** logo and name
|
||||
3. **Score OR countdown** (for upcoming matches - prioritizes countdown)
|
||||
4. **Away team** logo and name
|
||||
5. **Venue** with location emoji 📍 (if available)
|
||||
6. **Competition name** (only on "Všechny kategorie" tab)
|
||||
7. **Status badge** at the bottom
|
||||
|
||||
## Testing Recommendations
|
||||
|
||||
1. **"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
|
||||
|
||||
2. **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
|
||||
|
||||
3. **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
|
||||
|
||||
4. **Countdown Display**
|
||||
- Check upcoming matches show countdown
|
||||
- Verify countdown updates (wait 30 seconds)
|
||||
- Test with matches at different time ranges (days, hours, minutes)
|
||||
|
||||
5. **Czech Date Format**
|
||||
- Verify dates display as DD.MM.YYYY (e.g., 12.10.2025)
|
||||
- Check consistency across all match cards
|
||||
|
||||
6. **Status Badges**
|
||||
- Verify finished matches show "✓ Skončeno"
|
||||
- Check past matches without scores show "Odehráno"
|
||||
- Confirm future matches show "Nadcházející"
|
||||
|
||||
7. **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:**
|
||||
1. Added time check during data loading: `matchTime > Date.now()`
|
||||
2. Set score to `null` **ONLY for matches in the future**
|
||||
3. **Past matches keep their actual scores** from the API
|
||||
4. Changed display logic to prioritize countdown for future matches
|
||||
5. Now correctly shows countdown and "Nadcházející" status for future matches
|
||||
6. 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
|
||||
Reference in New Issue
Block a user