diff --git a/app/src/main/java/com/cornellappdev/score/components/EmptyState.kt b/app/src/main/java/com/cornellappdev/score/components/EmptyState.kt new file mode 100644 index 0000000..550efcd --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/components/EmptyState.kt @@ -0,0 +1,52 @@ +package com.cornellappdev.score.components + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import com.cornellappdev.score.R +import com.cornellappdev.score.theme.GrayMedium +import com.cornellappdev.score.theme.GrayPrimary +import com.cornellappdev.score.theme.Style.bodyNormal +import com.cornellappdev.score.theme.Style.heading2 + +@Composable +fun EmptyState( + modifier: Modifier = Modifier +) { + Column( + modifier = modifier, + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Image( + painter = painterResource(R.drawable.ic_speaker_gray), + contentDescription = "score speaker icon" + ) + Spacer(modifier = Modifier.height(16.dp)) + Text( + text = "No games yet.", + style = heading2.copy(color = GrayPrimary) + ) + Spacer(modifier = Modifier.height(8.dp)) + Text( + text = "Check back here later!", + style = bodyNormal.copy(color = GrayMedium) + ) + } +} + +@Preview +@Composable +private fun EmptyStatePreview() = ScorePreview { + EmptyState() +} \ No newline at end of file diff --git a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt index 6688183..ade877f 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/HomeScreen.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import com.cornellappdev.score.components.EmptyState import com.cornellappdev.score.components.ErrorState import com.cornellappdev.score.components.GameCard import com.cornellappdev.score.components.GamesCarousel @@ -101,21 +102,25 @@ private fun HomeLazyColumn( navigateToGameDetails: (String) -> Unit ) { LazyColumn(contentPadding = PaddingValues(top = 24.dp)) { - item { - Text( - text = "Latest", - style = heading1, - color = GrayPrimary, - modifier = Modifier - .fillMaxWidth() - .padding(start = 24.dp) - ) - } - item { - Spacer(Modifier.height(16.dp)) + if (uiState.filteredGames.isNotEmpty()) { + item { + Text( + text = "Upcoming", + style = heading1, + color = GrayPrimary, + modifier = Modifier + .fillMaxWidth() + .padding(start = 24.dp) + ) + } + item { + Spacer(Modifier.height(16.dp)) + } } - item { - GamesCarousel(uiState.upcomingGames, navigateToGameDetails) + if (uiState.filteredGames.isNotEmpty()) { + item { + GamesCarousel(uiState.upcomingGames, navigateToGameDetails) + } } stickyHeader { Column( @@ -146,24 +151,36 @@ private fun HomeLazyColumn( ) } } - item { - Spacer(modifier = Modifier.height(24.dp)) - } - items(uiState.filteredGames) { - val game = it - Column(modifier = Modifier.padding(horizontal = 24.dp)) { - GameCard( - teamLogo = game.teamLogo, - team = game.team, - date = game.dateString, - isLive = game.isLive, - genderIcon = painterResource(game.genderIcon), - sportIcon = painterResource(game.sportIcon), - location = game.location, - topCornerRound = true, - onClick = { navigateToGameDetails(game.id) } - ) - Spacer(modifier = Modifier.height(16.dp)) + + if (uiState.filteredGames.isNotEmpty()) { + item { + Spacer(modifier = Modifier.height(24.dp)) + } + items(uiState.filteredGames) { + val game = it + Column(modifier = Modifier.padding(horizontal = 24.dp)) { + GameCard( + teamLogo = game.teamLogo, + team = game.team, + date = game.dateString, + isLive = game.isLive, + genderIcon = painterResource(game.genderIcon), + sportIcon = painterResource(game.sportIcon), + location = game.location, + topCornerRound = true, + onClick = { navigateToGameDetails(game.id) } + ) + Spacer(modifier = Modifier.height(16.dp)) + } + } + } else { + item { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + EmptyState() + } } } } @@ -191,3 +208,19 @@ private fun HomeScreenPreview() = ScorePreview { } } +@Preview +@Composable +private fun HomeScreenEmptyStatePreview() = ScorePreview { + HomeContent( + HomeUiState( + selectedGender = GenderDivision.ALL, + sportSelect = SportSelection.All, + selectionList = sportSelectionList, + loadedState = ApiResponse.Success(emptyList()) + ), + onGenderSelected = {}, + onSportSelected = {}, + onRefresh = {} + ) +} + diff --git a/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt index 32f1cc1..b831741 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/PastGamesScreen.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding @@ -21,6 +22,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel +import com.cornellappdev.score.components.EmptyState import com.cornellappdev.score.components.ErrorState import com.cornellappdev.score.components.GamesCarousel import com.cornellappdev.score.components.LoadingScreen @@ -98,21 +100,26 @@ private fun PastGamesLazyColumn( navigateToGameDetails: (String) -> Unit ) { LazyColumn(contentPadding = PaddingValues(top = 24.dp)) { - item { - Text( - text = "Latest", - style = heading1, - color = GrayPrimary, - modifier = Modifier - .fillMaxWidth() - .padding(start = 24.dp) - ) - } - item { - Spacer(Modifier.height(16.dp)) + if (uiState.filteredGames.isNotEmpty()) { + item { + Text( + text = "Latest", + style = heading1, + color = GrayPrimary, + modifier = Modifier + .fillMaxWidth() + .padding(start = 24.dp) + ) + } + item { + Spacer(Modifier.height(16.dp)) + } } - item { - GamesCarousel(uiState.pastGames, navigateToGameDetails) + + if (uiState.filteredGames.isNotEmpty()) { + item { + GamesCarousel(uiState.pastGames, navigateToGameDetails) + } } stickyHeader { Column( @@ -146,14 +153,25 @@ private fun PastGamesLazyColumn( item { Spacer(modifier = Modifier.height(24.dp)) } - items(uiState.filteredGames) { - val game = it - Column(modifier = Modifier.padding(horizontal = 24.dp)) { - PastGameCard( - data = game, - onClick = { navigateToGameDetails(game.id) } - ) - Spacer(modifier = Modifier.height(16.dp)) + if (uiState.filteredGames.isNotEmpty()) { + items(uiState.filteredGames) { + val game = it + Column(modifier = Modifier.padding(horizontal = 24.dp)) { + PastGameCard( + data = game, + onClick = { navigateToGameDetails(game.id) } + ) + Spacer(modifier = Modifier.height(16.dp)) + } + } + } else{ + item{ + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + EmptyState() + } } } } @@ -173,4 +191,20 @@ private fun PastGamesPreview() = ScorePreview { onSportSelected = {}, onRefresh = {}, ) +} + +@Composable +@Preview +private fun PastGamesEmptyStatePreview() = ScorePreview { + PastGamesContent( + uiState = PastGamesUiState( + selectedGender = GenderDivision.ALL, + sportSelect = SportSelection.All, + selectionList = sportSelectionList, + loadedState = ApiResponse.Success(emptyList()) + ), + onGenderSelected = {}, + onSportSelected = {}, + onRefresh = {}, + ) } \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_speaker_gray.xml b/app/src/main/res/drawable/ic_speaker_gray.xml new file mode 100644 index 0000000..e04a616 --- /dev/null +++ b/app/src/main/res/drawable/ic_speaker_gray.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + +