feat(schedule): group games by sport instead of date
Games in schedule view now display in sport sections (MLB, NBA, etc.) with games sorted by date within each section. Each game row shows its date since the section header now shows sport instead. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -50,6 +50,21 @@ final class ScheduleViewModel {
|
||||
return grouped.sorted { $0.key < $1.key }.map { ($0.key, $0.value) }
|
||||
}
|
||||
|
||||
var gamesBySport: [(sport: Sport, games: [RichGame])] {
|
||||
let grouped = Dictionary(grouping: filteredGames) { game in
|
||||
game.game.sport
|
||||
}
|
||||
// Sort by sport order (use allCases index for consistent ordering)
|
||||
// Within each sport, games are sorted by date
|
||||
return grouped
|
||||
.sorted { lhs, rhs in
|
||||
let lhsIndex = Sport.allCases.firstIndex(of: lhs.key) ?? 0
|
||||
let rhsIndex = Sport.allCases.firstIndex(of: rhs.key) ?? 0
|
||||
return lhsIndex < rhsIndex
|
||||
}
|
||||
.map { (sport: $0.key, games: $0.value.sorted { $0.game.dateTime < $1.game.dateTime }) }
|
||||
}
|
||||
|
||||
var hasFilters: Bool {
|
||||
selectedSports.count < Sport.supported.count || !searchText.isEmpty
|
||||
}
|
||||
|
||||
@@ -89,14 +89,17 @@ struct ScheduleListView: View {
|
||||
.listRowBackground(Color.clear)
|
||||
}
|
||||
|
||||
ForEach(viewModel.gamesByDate, id: \.date) { dateGroup in
|
||||
ForEach(viewModel.gamesBySport, id: \.sport) { sportGroup in
|
||||
Section {
|
||||
ForEach(dateGroup.games) { richGame in
|
||||
GameRowView(game: richGame)
|
||||
ForEach(sportGroup.games) { richGame in
|
||||
GameRowView(game: richGame, showDate: true)
|
||||
}
|
||||
} header: {
|
||||
Text(formatSectionDate(dateGroup.date))
|
||||
.font(.headline)
|
||||
HStack(spacing: 8) {
|
||||
Image(systemName: sportGroup.sport.iconName)
|
||||
Text(sportGroup.sport.rawValue)
|
||||
}
|
||||
.font(.headline)
|
||||
}
|
||||
.listRowBackground(Theme.cardBackground(colorScheme))
|
||||
}
|
||||
@@ -204,9 +207,18 @@ struct SportFilterChip: View {
|
||||
|
||||
struct GameRowView: View {
|
||||
let game: RichGame
|
||||
var showDate: Bool = false
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
// Date (when grouped by sport)
|
||||
if showDate {
|
||||
Text(formattedDate)
|
||||
.font(.caption)
|
||||
.fontWeight(.medium)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
|
||||
// Teams
|
||||
HStack {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
@@ -220,11 +232,6 @@ struct GameRowView: View {
|
||||
}
|
||||
|
||||
Spacer()
|
||||
|
||||
// Sport badge
|
||||
Image(systemName: game.game.sport.iconName)
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
}
|
||||
|
||||
// Game info
|
||||
@@ -241,6 +248,12 @@ struct GameRowView: View {
|
||||
}
|
||||
.padding(.vertical, 4)
|
||||
}
|
||||
|
||||
private var formattedDate: String {
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateFormat = "EEE, MMM d"
|
||||
return formatter.string(from: game.game.dateTime)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Team Badge
|
||||
|
||||
Reference in New Issue
Block a user