diff --git a/app/src/main/java/com/cornellappdev/score/screen/EmptyProfileScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/EmptyProfileScreen.kt index a133c59..9096c86 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/EmptyProfileScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/EmptyProfileScreen.kt @@ -53,12 +53,18 @@ fun EmptyProfileScreen(modifier: Modifier = Modifier) { var selectedPicture by rememberSaveable { mutableStateOf(ProfilePicture.BLANK) } var editingPicture by rememberSaveable { mutableStateOf(false) } - BackHandler(enabled = editingPicture) { editingPicture = false } + var showingSettings by rememberSaveable { mutableStateOf(false) } + BackHandler(enabled = editingPicture || showingSettings) { + editingPicture = false + showingSettings = false + } Column(modifier .fillMaxSize() .background(Color.White)) { Box(Modifier.weight(1f)) { - if (editingPicture) { + if (showingSettings) { + SettingsScreen(onBack = { showingSettings = false }) + } else if (editingPicture) { EditProfileScreen( selectedPicture = selectedPicture, onPictureSelected = { selectedPicture = it }, @@ -67,11 +73,12 @@ fun EmptyProfileScreen(modifier: Modifier = Modifier) { } else { EmptyProfileContent( selectedPicture = selectedPicture, - onEditProfilePicture = { editingPicture = true } + onEditProfilePicture = { editingPicture = true }, + onSettings = { showingSettings = true } ) } } - ProfileTabBar() + if (!showingSettings) ProfileTabBar() } } @@ -80,7 +87,8 @@ fun EmptyProfileScreen(modifier: Modifier = Modifier) { fun EmptyProfileContent( selectedPicture: ProfilePicture, onEditProfilePicture: () -> Unit, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + onSettings: () -> Unit = {} ) { Column( modifier @@ -89,7 +97,7 @@ fun EmptyProfileContent( .padding(horizontal = 24.dp) .padding(top = 8.dp, bottom = 32.dp) ) { - ProfileIdentityHeader(selectedPicture, onEditProfilePicture) + ProfileIdentityHeader(selectedPicture, onEditProfilePicture, onSettings = onSettings) ProfileSectionDivider() ProfileSectionHeading(R.string.profile_favorite_sports, R.string.profile_edit, Color.Black) Spacer(Modifier.height(16.dp)) @@ -163,7 +171,8 @@ internal fun ProfileIdentityHeader( selectedPicture: ProfilePicture, onEditProfilePicture: () -> Unit, compact: Boolean = false, - displayName: String = stringResource(R.string.profile_placeholder_name) + displayName: String = stringResource(R.string.profile_placeholder_name), + onSettings: () -> Unit = {} ) { Column { Row(Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) { @@ -181,7 +190,7 @@ internal fun ProfileIdentityHeader( Icon( painterResource(R.drawable.profile_settings), stringResource(R.string.profile_settings), - Modifier.size(32.dp), + Modifier.size(32.dp).clickable(role = Role.Button, onClick = onSettings), tint = Color.Unspecified ) } diff --git a/app/src/main/java/com/cornellappdev/score/screen/ProfileScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/ProfileScreen.kt index 7bd61b3..090fdf2 100644 --- a/app/src/main/java/com/cornellappdev/score/screen/ProfileScreen.kt +++ b/app/src/main/java/com/cornellappdev/score/screen/ProfileScreen.kt @@ -74,6 +74,7 @@ fun ProfileScreen( var selectedPicture by rememberSaveable { mutableStateOf(ProfilePicture.TENNIS) } var editingPicture by rememberSaveable { mutableStateOf(false) } + var showingSettings by rememberSaveable { mutableStateOf(false) } var editingSports by rememberSaveable { mutableStateOf(false) } var favorites by rememberSaveable( data.favorites, @@ -88,13 +89,16 @@ fun ProfileScreen( ) ) { mutableStateOf(data.favorites) } - BackHandler(enabled = editingPicture || editingSports) { + BackHandler(enabled = editingPicture || editingSports || showingSettings) { editingPicture = false editingSports = false + showingSettings = false } Column(modifier.fillMaxSize().background(Color.White)) { Box(Modifier.weight(1f)) { - if (editingSports) { + if (showingSettings) { + SettingsScreen(onBack = { showingSettings = false }) + } else if (editingSports) { EditFavoriteSportsScreen( favorites = favorites, onToggleFavorite = { favorite -> @@ -117,11 +121,12 @@ fun ProfileScreen( editingSports = true onEditSports() }, - onShowAllBookmarks = onShowAllBookmarks + onShowAllBookmarks = onShowAllBookmarks, + onSettings = { showingSettings = true } ) } } - if (!editingSports) ProfileTabBar() + if (!editingSports && !showingSettings) ProfileTabBar() } } @@ -133,7 +138,8 @@ fun ProfileContent( onEditProfilePicture: () -> Unit, onEditSports: () -> Unit, onShowAllBookmarks: () -> Unit, - modifier: Modifier = Modifier + modifier: Modifier = Modifier, + onSettings: () -> Unit = {} ) { Column( modifier.fillMaxSize().verticalScroll(rememberScrollState()) @@ -144,7 +150,8 @@ fun ProfileContent( selectedPicture, onEditProfilePicture, compact = true, - displayName = data.name + displayName = data.name, + onSettings = onSettings ) ProfileSectionDivider() ProfileActionHeading( diff --git a/app/src/main/java/com/cornellappdev/score/screen/SettingsScreen.kt b/app/src/main/java/com/cornellappdev/score/screen/SettingsScreen.kt new file mode 100644 index 0000000..d91df28 --- /dev/null +++ b/app/src/main/java/com/cornellappdev/score/screen/SettingsScreen.kt @@ -0,0 +1,132 @@ +package com.cornellappdev.score.screen + +import androidx.annotation.DrawableRes +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.semantics.Role +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.cornellappdev.score.R +import com.cornellappdev.score.components.NavigationHeader +import com.cornellappdev.score.theme.CrimsonPrimary +import com.cornellappdev.score.theme.GrayMedium +import com.cornellappdev.score.theme.GrayPrimary +import com.cornellappdev.score.theme.GrayStroke +import com.cornellappdev.score.theme.Style + +@Composable +fun SettingsScreen(onBack: () -> Unit, modifier: Modifier = Modifier) { + Column(modifier.fillMaxSize().background(Color.White)) { + NavigationHeader(stringResource(R.string.profile_settings), onBack) + Column( + Modifier.fillMaxWidth().verticalScroll(rememberScrollState()).padding(24.dp, 32.dp), + verticalArrangement = Arrangement.spacedBy(28.dp) + ) { + SettingsSection(stringResource(R.string.settings_preferences)) { + SettingsRow( + stringResource(R.string.profile_favorite_sports), + R.drawable.settings_star + ) + HorizontalDivider(color = GrayStroke) + SettingsRow( + stringResource(R.string.profile_notifications), + R.drawable.settings_notifications, + iconSize = 28.dp + ) + } + SettingsSection(stringResource(R.string.settings_help)) { + SettingsRow( + stringResource(R.string.settings_about), + R.drawable.settings_info, + iconSize = 33.dp + ) + HorizontalDivider(color = GrayStroke) + SettingsRow(stringResource(R.string.settings_report), R.drawable.settings_flag) + HorizontalDivider(color = GrayStroke) + SettingsRow( + stringResource(R.string.settings_logout), + R.drawable.settings_logout, + destructive = true + ) + HorizontalDivider(color = GrayStroke) + SettingsRow( + stringResource(R.string.settings_delete), + R.drawable.settings_delete, + destructive = true + ) + } + } + } +} + +@Composable +private fun SettingsSection(title: String, content: @Composable () -> Unit) { + Column(verticalArrangement = Arrangement.spacedBy(12.dp)) { + Text(title, style = Style.bodyMedium, color = GrayPrimary) + Column( + Modifier.fillMaxWidth().border(1.dp, GrayStroke, RoundedCornerShape(16.dp)) + .padding(start = 16.dp, end = 20.dp), + content = { content() } + ) + } +} + +@Composable +private fun SettingsRow( + title: String, + @DrawableRes icon: Int, + iconSize: Dp = 30.dp, + destructive: Boolean = false +) { + // Placeholder actions intentionally do nothing until the settings flows are implemented. + Row( + Modifier.fillMaxWidth().clickable(role = Role.Button, onClick = {}) + .padding(vertical = 16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + Icon(painterResource(icon), null, Modifier.size(iconSize), tint = Color.Unspecified) + Spacer(Modifier.width(10.dp)) + Text( + title, style = Style.bodyMedium.copy(fontSize = 16.sp), + color = if (destructive) CrimsonPrimary else GrayPrimary, modifier = Modifier.weight(1f) + ) + if (!destructive) { + Icon( + painterResource(R.drawable.ic_right_chevron), + null, + Modifier.size(24.dp), + tint = GrayMedium + ) + } + } +} + +@Preview(showBackground = true, widthDp = 393, heightDp = 805) +@Composable +private fun SettingsScreenPreview() { + SettingsScreen(onBack = {}) +} diff --git a/app/src/main/res/drawable/settings_delete.xml b/app/src/main/res/drawable/settings_delete.xml new file mode 100644 index 0000000..dc52506 --- /dev/null +++ b/app/src/main/res/drawable/settings_delete.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/settings_flag.xml b/app/src/main/res/drawable/settings_flag.xml new file mode 100644 index 0000000..7a19e7b --- /dev/null +++ b/app/src/main/res/drawable/settings_flag.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/settings_info.xml b/app/src/main/res/drawable/settings_info.xml new file mode 100644 index 0000000..77077dd --- /dev/null +++ b/app/src/main/res/drawable/settings_info.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/settings_logout.xml b/app/src/main/res/drawable/settings_logout.xml new file mode 100644 index 0000000..cf3e5be --- /dev/null +++ b/app/src/main/res/drawable/settings_logout.xml @@ -0,0 +1,12 @@ + + + + diff --git a/app/src/main/res/drawable/settings_notifications.xml b/app/src/main/res/drawable/settings_notifications.xml new file mode 100644 index 0000000..296dd0d --- /dev/null +++ b/app/src/main/res/drawable/settings_notifications.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/settings_star.xml b/app/src/main/res/drawable/settings_star.xml new file mode 100644 index 0000000..117e18d --- /dev/null +++ b/app/src/main/res/drawable/settings_star.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1551dc4..26545d4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -22,4 +22,10 @@ Scores Highlights Edit Favorite Sports + Preferences + Help + About Score + Report an Issue + Log Out + Delete Account \ No newline at end of file