settings ui

This commit is contained in:
inhale-dir 2024-12-10 20:32:00 +01:00
parent 35a2074539
commit 848c91379a
15 changed files with 662 additions and 1710 deletions

15
.gitignore vendored Normal file
View File

@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties

3
.idea/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

6
.idea/compiler.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="21" />
</component>
</project>

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetSelector">
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
</SelectionState>
</selectionStates>
</component>
</project>

20
.idea/gradle.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="CHOOSE_PER_TEST" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="#GRADLE_LOCAL_JAVA_HOME" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveExternalAnnotations" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,57 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="ComposePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="ComposePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewDimensionRespectsLimit" enabled="true" level="WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewMustBeTopLevelFunction" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNeedsComposableAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="GlancePreviewNotSupportedInUnitTestFiles" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewAnnotationInFunctionWithParameters" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewApiLevelMustBeValid" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewDeviceShouldUseNewSpec" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewFontScaleMustBeGreaterThanZero" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewMultipleParameterProviders" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
<inspection_tool class="PreviewPickerAnnotation" enabled="true" level="ERROR" enabled_by_default="true">
<option name="composableFile" value="true" />
<option name="previewFile" value="true" />
</inspection_tool>
</profile>
</component>

6
.idea/kotlinc.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.9.22" />
</component>
</project>

10
.idea/migrations.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectMigrations">
<option name="MigrateToGradleLocalJavaHome">
<set>
<option value="$PROJECT_DIR$" />
</set>
</option>
</component>
</project>

10
.idea/misc.xml Normal file
View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="com.intellij.execution.junit.AbstractAllInDirectoryConfigurationProducer" />
<option value="com.intellij.execution.junit.AllInPackageConfigurationProducer" />
<option value="com.intellij.execution.junit.PatternConfigurationProducer" />
<option value="com.intellij.execution.junit.TestInClassConfigurationProducer" />
<option value="com.intellij.execution.junit.UniqueIdConfigurationProducer" />
<option value="com.intellij.execution.junit.testDiscovery.JUnitTestDiscoveryConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinJUnitRunConfigurationProducer" />
<option value="org.jetbrains.kotlin.idea.junit.KotlinPatternConfigurationProducer" />
</set>
</option>
</component>
</project>

6
.idea/vcs.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>

View File

@ -88,4 +88,5 @@ dependencies {
implementation("androidx.compose.material:material-icons-core:1.6.2")
implementation("androidx.compose.material:material-icons-extended:1.6.2")
implementation("androidx.compose.material3:material3:1.2.0")
implementation("androidx.core:core-ktx:1.12.0")
}

View File

@ -18,13 +18,26 @@ class SettingsDataStore(private val context: Context) {
val RADIUS = intPreferencesKey("radius")
val API_KEY = stringPreferencesKey("api_key")
val FAVORITE_STATIONS = stringPreferencesKey("favorite_stations")
val LOCATION_MODE_KEY = stringPreferencesKey("location_mode")
val STATIC_LAT_KEY = doublePreferencesKey("static_lat")
val STATIC_LNG_KEY = doublePreferencesKey("static_lng")
val GPS_LAT_KEY = doublePreferencesKey("gps_lat")
val GPS_LNG_KEY = doublePreferencesKey("gps_lng")
}
val selectedLocation: Flow<Pair<Double, Double>> = context.dataStore.data.map { preferences ->
Pair(
preferences[PreferencesKeys.LAT_KEY] ?: 52.520008, // Default to Berlin
preferences[PreferencesKeys.LNG_KEY] ?: 13.404954
)
val mode = preferences[PreferencesKeys.LOCATION_MODE_KEY] ?: "static"
when (mode) {
"static" -> Pair(
preferences[PreferencesKeys.STATIC_LAT_KEY] ?: 52.520008,
preferences[PreferencesKeys.STATIC_LNG_KEY] ?: 13.404954
)
"gps" -> Pair(
preferences[PreferencesKeys.GPS_LAT_KEY] ?: preferences[PreferencesKeys.STATIC_LAT_KEY] ?: 52.520008,
preferences[PreferencesKeys.GPS_LNG_KEY] ?: preferences[PreferencesKeys.STATIC_LNG_KEY] ?: 13.404954
)
else -> Pair(52.520008, 13.404954)
}
}
val selectedFuelType: Flow<String> = context.dataStore.data.map { preferences ->
@ -44,10 +57,23 @@ class SettingsDataStore(private val context: Context) {
if (favoritesString.isEmpty()) setOf() else favoritesString.split(",").toSet()
}
suspend fun saveLocation(latitude: Double, longitude: Double) {
val locationMode: Flow<String> = context.dataStore.data.map { preferences ->
preferences[PreferencesKeys.LOCATION_MODE_KEY] ?: "static" // Default to static mode
}
suspend fun saveLocation(latitude: Double, longitude: Double, mode: String? = null) {
context.dataStore.edit { preferences ->
preferences[PreferencesKeys.LAT_KEY] = latitude
preferences[PreferencesKeys.LNG_KEY] = longitude
val currentMode = mode ?: preferences[PreferencesKeys.LOCATION_MODE_KEY] ?: "static"
when (currentMode) {
"static" -> {
preferences[PreferencesKeys.STATIC_LAT_KEY] = latitude
preferences[PreferencesKeys.STATIC_LNG_KEY] = longitude
}
"gps" -> {
preferences[PreferencesKeys.GPS_LAT_KEY] = latitude
preferences[PreferencesKeys.GPS_LNG_KEY] = longitude
}
}
}
}
@ -85,4 +111,10 @@ class SettingsDataStore(private val context: Context) {
preferences[PreferencesKeys.FAVORITE_STATIONS] = currentFavorites.joinToString(",")
}
}
suspend fun saveLocationMode(mode: String) {
context.dataStore.edit { preferences ->
preferences[PreferencesKeys.LOCATION_MODE_KEY] = mode
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,13 @@
package com.example.tank.ui.screens
import android.Manifest
import android.content.pm.PackageManager
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.material.icons.filled.LocationOn
import androidx.compose.material.icons.filled.MyLocation
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -11,7 +17,16 @@ import androidx.navigation.NavController
import androidx.navigation.compose.rememberNavController
import com.example.tank.data.SettingsDataStore
import com.example.tank.di.NetworkModule
import com.google.android.gms.location.LocationServices
import com.google.android.gms.location.Priority
import kotlinx.coroutines.launch
import androidx.compose.material.icons.Icons
import androidx.core.content.ContextCompat
import androidx.compose.foundation.background
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.draw.clip
import androidx.compose.foundation.verticalScroll
import androidx.compose.foundation.rememberScrollState
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@ -20,21 +35,58 @@ fun SettingsScreen(navController: NavController) {
val settingsDataStore = remember { SettingsDataStore(context) }
val scope = rememberCoroutineScope()
var fuelExpanded by remember { mutableStateOf(false) }
var selectedFuelType by remember { mutableStateOf("") }
var selectedLocation by remember { mutableStateOf<Pair<Double, Double>?>(null) }
var radiusExpanded by remember { mutableStateOf(false) }
var selectedRadius by remember { mutableStateOf(5) }
var apiKey by remember { mutableStateOf("") }
var locationMode by remember { mutableStateOf("static") }
val fuelTypes = listOf(
"DIESEL" to "Diesel",
"E5" to "Super E5",
"E10" to "Super E10",
"Diesel" to "Diesel"
"E10" to "Super E10"
)
val radiusOptions = listOf(5, 10, 15, 20)
// Add location services client
val fusedLocationClient = remember {
LocationServices.getFusedLocationProviderClient(context)
}
// Permission launcher
val locationPermissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestMultiplePermissions()
) { permissions ->
val locationGranted = permissions.entries.all { it.value }
if (locationGranted) {
scope.launch {
settingsDataStore.saveLocationMode("gps")
locationMode = "gps"
try {
fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, null)
.addOnSuccessListener { location ->
if (location != null) {
scope.launch {
settingsDataStore.saveLocation(location.latitude, location.longitude)
selectedLocation = Pair(location.latitude, location.longitude)
}
}
}
} catch (e: SecurityException) {
// Handle permission denial
}
}
}
}
// Collect location mode
LaunchedEffect(Unit) {
settingsDataStore.locationMode.collect { mode ->
locationMode = mode
}
}
LaunchedEffect(Unit) {
settingsDataStore.selectedFuelType.collect { fuelType ->
selectedFuelType = fuelType.uppercase()
@ -57,132 +109,280 @@ fun SettingsScreen(navController: NavController) {
LaunchedEffect(Unit) {
settingsDataStore.apiKey.collect { key ->
apiKey = key ?: NetworkModule.DEFAULT_API_KEY
apiKey = key
}
}
LaunchedEffect(locationMode) {
if (locationMode == "gps" &&
ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
try {
fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, null)
.addOnSuccessListener { location ->
if (location != null) {
scope.launch {
settingsDataStore.saveLocation(
location.latitude,
location.longitude,
"gps"
)
selectedLocation = Pair(location.latitude, location.longitude)
}
}
}
} catch (e: SecurityException) {
// Handle permission denial
}
}
}
Column(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.verticalScroll(rememberScrollState())
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// Header
Text(
text = "Settings",
style = MaterialTheme.typography.headlineMedium
style = MaterialTheme.typography.headlineMedium,
color = MaterialTheme.colorScheme.primary,
modifier = Modifier.padding(bottom = 8.dp)
)
// Add API Key TextField
OutlinedTextField(
value = apiKey,
onValueChange = { apiKey = it },
label = { Text("API Key") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
supportingText = { Text("Leave empty to use default key") }
)
// Location Selection
Text(
text = "Select Location",
style = MaterialTheme.typography.titleMedium
)
Button(
onClick = { navController.navigate("map") },
modifier = Modifier.fillMaxWidth()
) {
Text(if (selectedLocation != null) {
"Selected: ${String.format("%.4f", selectedLocation!!.first)}, ${String.format("%.4f", selectedLocation!!.second)}"
} else {
"Select Location on Map"
})
}
// Fuel Type Selection
Text(
text = "Select Fuel Type",
style = MaterialTheme.typography.titleMedium
)
ExposedDropdownMenuBox(
expanded = fuelExpanded,
onExpandedChange = { fuelExpanded = !fuelExpanded }
) {
TextField(
value = when (selectedFuelType.uppercase()) {
"E5" -> "Super E5"
"E10" -> "Super E10"
"DIESEL" -> "Diesel"
else -> ""
},
onValueChange = {},
readOnly = true,
placeholder = { Text("Select fuel type") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = fuelExpanded) },
modifier = Modifier.menuAnchor()
)
ExposedDropdownMenu(
expanded = fuelExpanded,
onDismissRequest = { fuelExpanded = false }
// Location Section
SettingsSection(title = "Location") {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
fuelTypes.forEach { (type, label) ->
DropdownMenuItem(
text = { Text(label) },
// Location Mode Selection
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
FilterChip(
selected = locationMode == "static",
onClick = {
selectedFuelType = type
fuelExpanded = false
scope.launch {
settingsDataStore.saveFuelType(type.lowercase())
settingsDataStore.saveLocationMode("static")
locationMode = "static"
}
},
label = { Text("Static") },
leadingIcon = {
Icon(
Icons.Default.LocationOn,
contentDescription = "Static Location"
)
},
colors = FilterChipDefaults.filterChipColors(
selectedContainerColor = MaterialTheme.colorScheme.primaryContainer,
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
)
FilterChip(
selected = locationMode == "gps",
onClick = {
if (ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION
) == PackageManager.PERMISSION_GRANTED
) {
scope.launch {
settingsDataStore.saveLocationMode("gps")
locationMode = "gps"
try {
fusedLocationClient.getCurrentLocation(Priority.PRIORITY_HIGH_ACCURACY, null)
.addOnSuccessListener { location ->
if (location != null) {
scope.launch {
settingsDataStore.saveLocation(
location.latitude,
location.longitude,
"gps"
)
selectedLocation = Pair(location.latitude, location.longitude)
}
}
}
} catch (e: SecurityException) {
// Handle permission denial
}
}
} else {
locationPermissionLauncher.launch(
arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
)
}
},
label = { Text("GPS") },
leadingIcon = {
Icon(
Icons.Default.MyLocation,
contentDescription = "GPS Location"
)
},
colors = FilterChipDefaults.filterChipColors(
selectedContainerColor = MaterialTheme.colorScheme.primaryContainer,
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
)
}
// Only show location card for static mode
if (locationMode == "static") {
Card(
modifier = Modifier
.fillMaxWidth()
.height(48.dp),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surfaceVariant,
)
) {
Row(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 12.dp),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
) {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Icon(
imageVector = if (locationMode == "static")
Icons.Default.LocationOn
else Icons.Default.MyLocation,
contentDescription = null,
tint = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.size(20.dp)
)
Text(
text = if (selectedLocation != null) {
String.format(
"%.4f, %.4f",
selectedLocation!!.first,
selectedLocation!!.second
)
} else {
"No location selected"
},
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
}
TextButton(
onClick = { navController.navigate("map") },
contentPadding = PaddingValues(horizontal = 8.dp)
) {
Text(
"Map",
style = MaterialTheme.typography.bodyMedium
)
}
}
)
}
}
}
}
// Radius Selection
Text(
text = "Search Radius",
style = MaterialTheme.typography.titleMedium
)
ExposedDropdownMenuBox(
expanded = radiusExpanded,
onExpandedChange = { radiusExpanded = !radiusExpanded }
) {
TextField(
value = "$selectedRadius km",
onValueChange = {},
readOnly = true,
placeholder = { Text("Select radius") },
trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = radiusExpanded) },
modifier = Modifier.menuAnchor()
)
ExposedDropdownMenu(
expanded = radiusExpanded,
onDismissRequest = { radiusExpanded = false }
// Fuel Preferences Section
SettingsSection(title = "Fuel Preferences") {
Column(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
radiusOptions.forEach { radius ->
DropdownMenuItem(
text = { Text("$radius km") },
onClick = {
selectedRadius = radius
radiusExpanded = false
scope.launch {
settingsDataStore.saveRadius(radius)
}
}
// Fuel Type Selection
Text(
"Fuel Type",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
fuelTypes.forEach { (type, label) ->
FilterChip(
selected = selectedFuelType.uppercase() == type,
onClick = {
selectedFuelType = type
scope.launch {
settingsDataStore.saveFuelType(type.lowercase())
}
},
label = { Text(label) },
colors = FilterChipDefaults.filterChipColors(
selectedContainerColor = MaterialTheme.colorScheme.primaryContainer,
containerColor = MaterialTheme.colorScheme.surfaceVariant
)
)
}
}
// Radius Selection
Column(
verticalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
"Search Radius",
style = MaterialTheme.typography.bodyMedium,
color = MaterialTheme.colorScheme.onSurfaceVariant
)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
radiusOptions.forEach { radius ->
FilterChip(
selected = selectedRadius == radius,
onClick = {
selectedRadius = radius
scope.launch {
settingsDataStore.saveRadius(radius)
}
},
label = { Text("${radius}km") },
colors = FilterChipDefaults.filterChipColors(
selectedContainerColor = MaterialTheme.colorScheme.primaryContainer
)
)
}
}
}
}
}
Spacer(modifier = Modifier.weight(1f))
// API Settings Section
SettingsSection(title = "API Settings") {
OutlinedTextField(
value = apiKey,
onValueChange = { apiKey = it },
label = { Text("API Key") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
supportingText = { Text("Leave empty to use default key") },
colors = OutlinedTextFieldDefaults.colors(
focusedBorderColor = MaterialTheme.colorScheme.primary,
unfocusedBorderColor = MaterialTheme.colorScheme.outline
)
)
}
Spacer(modifier = Modifier.height(16.dp))
// Save Button
Button(
onClick = {
scope.launch {
@ -192,19 +392,45 @@ fun SettingsScreen(navController: NavController) {
if (selectedFuelType.isNotEmpty()) {
settingsDataStore.saveFuelType(selectedFuelType.lowercase())
}
// Save API key
settingsDataStore.saveApiKey(apiKey)
// Update NetworkModule
NetworkModule.updateApiKey(apiKey)
navController.popBackStack()
}
},
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 16.dp),
enabled = selectedLocation != null && selectedFuelType.isNotEmpty()
.padding(bottom = 8.dp),
enabled = selectedLocation != null && selectedFuelType.isNotEmpty(),
colors = ButtonDefaults.buttonColors(
containerColor = MaterialTheme.colorScheme.primary,
contentColor = MaterialTheme.colorScheme.onPrimary,
disabledContainerColor = MaterialTheme.colorScheme.surfaceVariant,
disabledContentColor = MaterialTheme.colorScheme.onSurfaceVariant
)
) {
Text("Save and Return")
}
}
}
@Composable
private fun SettingsSection(
title: String,
content: @Composable () -> Unit
) {
Column(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(12.dp))
.background(MaterialTheme.colorScheme.surface)
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
Text(
text = title,
style = MaterialTheme.typography.titleMedium,
color = MaterialTheme.colorScheme.primary
)
content()
}
}