HomePage.kt
The snippet can be accessed without any authentication.
Authored by
a6-alrashdi
HomePage.kt 7.95 KiB
package com.example.match.ui.home
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.example.match.model.Fixture
import com.example.match.model.LiveScore
import com.example.match.ui.common.AppFooter
import com.example.match.ui.common.AppHeader
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@Composable
fun HomePage(
liveScores: List<LiveScore>,
upcomingMatches: List<Fixture>,
currentTab: String,
onNavigationClick: (String) -> Unit,
navController: NavController
) {
val currentTime = System.currentTimeMillis()
val oneDayMillis = 24 * 60 * 60 * 1000
val todayStart = currentTime - (currentTime % oneDayMillis)
val tomorrowStart = todayStart + oneDayMillis
val todayMatchesGrouped = liveScores.filter {
val matchTimeMs = it.matchTime?.times(1000) ?: 0L
matchTimeMs in todayStart until tomorrowStart
}.groupBy { it.leagueName ?: "Unknown League" }
// Group upcoming matches by date
val upcomingMatchesByDate = upcomingMatches.groupBy { fixture ->
fixture.matchTime?.let { time ->
val matchDate = Date(time * 1000L)
val tomorrowStartSeconds = tomorrowStart / 1000
val tomorrowEndSeconds = (tomorrowStart + oneDayMillis) / 1000
when {
time in tomorrowStartSeconds until tomorrowEndSeconds -> "Tomorrow"
else -> SimpleDateFormat("EEEE, MMM d", Locale.getDefault()).format(matchDate)
}
} ?: "Unknown Date"
}
Column(
modifier = Modifier.fillMaxSize()
) {
AppHeader(title = "Home")
LazyColumn(
modifier = Modifier
.weight(1f)
.fillMaxSize(),
contentPadding = PaddingValues(16.dp)
) {
// Today’s Matches
if (todayMatchesGrouped.isNotEmpty()) {
item {
Text(
text = "Today's Matches",
style = MaterialTheme.typography.titleMedium
)
}
todayMatchesGrouped.forEach { (leagueName, matches) ->
item { LeagueHeader(leagueName = leagueName) }
items(matches) { match: LiveScore ->
LiveScoreCard(
liveScore = match,
navController = navController
)
}
item { Divider() }
}
}
// Upcoming Matches
if (upcomingMatchesByDate.isNotEmpty()) {
item {
Text(
text = "Upcoming Matches",
style = MaterialTheme.typography.titleMedium
)
}
upcomingMatchesByDate.forEach { (date, matches) ->
item {
Text(
text = date,
style = MaterialTheme.typography.bodyLarge
)
}
matches.groupBy { it.leagueName ?: "Unknown League" }
.forEach { (leagueName, leagueMatches) ->
item { LeagueHeader(leagueName = leagueName) }
items(leagueMatches) { match: Fixture ->
FixtureCard(
fixture = match,
navController = navController
)
}
item { Divider() }
}
}
}
}
AppFooter(
currentTab = currentTab,
onNavigationClick = onNavigationClick
)
}
}
@Composable
fun LiveScoreCard(
liveScore: LiveScore,
navController: NavController
) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
.clickable {
navController.navigate("matchDetail/${liveScore.matchId}")
},
elevation = CardDefaults.cardElevation(4.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(text = liveScore.homeName ?: "Home Team", style = MaterialTheme.typography.bodyLarge)
if (liveScore.status != 0) {
Text(
text = "${liveScore.homeScore ?: 0} - ${liveScore.awayScore ?: 0}",
style = MaterialTheme.typography.bodyLarge
)
} else {
Text("vs", style = MaterialTheme.typography.bodyMedium)
}
Text(text = liveScore.awayName ?: "Away Team", style = MaterialTheme.typography.bodyLarge)
}
Spacer(modifier = Modifier.height(8.dp))
Text(
text = when (liveScore.status) {
1 -> "First Half (${liveScore.minute ?: "-"})"
3 -> "Second Half (${liveScore.minute ?: "-"})"
4 -> "Extra Time (${liveScore.minute ?: "-"})"
2 -> "Half-Time"
-1 -> "Finished"
0 -> {
val formattedTime = liveScore.matchTime?.let {
SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(it * 1000L))
} ?: "Time not available"
"Not Started (Kickoff: $formattedTime)"
}
else -> "Unknown Status"
},
style = MaterialTheme.typography.bodyMedium
)
}
}
}
@Composable
fun FixtureCard(
fixture: Fixture,
navController: NavController
) {
Card(
modifier = Modifier
.fillMaxWidth()
.padding(8.dp)
.clickable {
navController.navigate("matchDetail/${fixture.matchId}")
},
elevation = CardDefaults.cardElevation(4.dp)
) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(text = fixture.homeName ?: "Home Team", style = MaterialTheme.typography.bodyLarge)
Text("vs", style = MaterialTheme.typography.bodyMedium)
Text(text = fixture.awayName ?: "Away Team", style = MaterialTheme.typography.bodyLarge)
}
Spacer(modifier = Modifier.height(8.dp))
val formattedTime = fixture.matchTime?.let {
SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(it * 1000L))
} ?: "Time not available"
Text(
text = "Kickoff: $formattedTime",
style = MaterialTheme.typography.bodyMedium
)
}
}
}
@Composable
fun LeagueHeader(leagueName: String) {
Text(
text = leagueName,
modifier = Modifier.padding(vertical = 8.dp),
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.primary
)
}
Please register or sign in to comment