From 56c61d38a1cfbc4a42d59f603da385c8139f2890 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Ahlers?= Date: Thu, 4 Dec 2025 09:26:19 +0100 Subject: [PATCH] Add `CreatePage` with text input, dropdown, modal map, and location services; refactor `MapPage` and `ContentScreen` for `MapViewModel` injection --- .../jadehs/strassenschadenpro2/MainScreen.kt | 7 +- .../strassenschadenpro2/pages/CreatePage.kt | 109 +++++++++++++++++- .../strassenschadenpro2/pages/MapPage.kt | 10 +- 3 files changed, 115 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/de/jadehs/strassenschadenpro2/MainScreen.kt b/app/src/main/java/de/jadehs/strassenschadenpro2/MainScreen.kt index c8dd9e4..4b8fbd7 100644 --- a/app/src/main/java/de/jadehs/strassenschadenpro2/MainScreen.kt +++ b/app/src/main/java/de/jadehs/strassenschadenpro2/MainScreen.kt @@ -1,7 +1,6 @@ package de.jadehs.strassenschadenpro2 import android.app.Application -import android.util.Log import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons @@ -59,10 +58,10 @@ fun MainScreen(modifier: Modifier = Modifier, application: Application) { @Composable fun ContentScreen(modifier: Modifier = Modifier, selectedIndex: Int, application: Application) { - + val mapViewModel = remember { MapViewModel(application) } when(selectedIndex) { - 0 -> MapPage(application=application) - 1 -> CreatePage() + 0 -> MapPage(modifier = modifier, mapViewModel = mapViewModel) + 1 -> CreatePage(modifier = modifier, mapViewModel = mapViewModel) 2 -> ListPage() 3 -> SettingsPage() } diff --git a/app/src/main/java/de/jadehs/strassenschadenpro2/pages/CreatePage.kt b/app/src/main/java/de/jadehs/strassenschadenpro2/pages/CreatePage.kt index e73c2f8..f46c5a8 100644 --- a/app/src/main/java/de/jadehs/strassenschadenpro2/pages/CreatePage.kt +++ b/app/src/main/java/de/jadehs/strassenschadenpro2/pages/CreatePage.kt @@ -1,10 +1,115 @@ package de.jadehs.strassenschadenpro2.pages +import android.util.Log +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.unit.dp +import com.arcgismaps.location.LocationDisplayAutoPanMode +import com.arcgismaps.toolkit.geoviewcompose.MapView +import com.arcgismaps.toolkit.geoviewcompose.rememberLocationDisplay +import de.jadehs.strassenschadenpro2.MapViewModel +import de.jadehs.strassenschadenpro2.components.DropDownMenuBox +import kotlinx.coroutines.launch +@OptIn(ExperimentalMaterial3Api::class) @Composable -fun CreatePage(modifier: Modifier = Modifier) { - Text("Erstellen") +fun CreatePage(modifier: Modifier = Modifier, mapViewModel: MapViewModel) { + var beschreibungTextFieldValue = remember { mutableStateOf(TextFieldValue("")) } + + var currentDamageType = remember { mutableStateOf("")} + + var showModalBottomSheet = remember { mutableStateOf(false) } + + val locationDisplay = rememberLocationDisplay().apply { + setAutoPanMode(LocationDisplayAutoPanMode.Off) + } + + val context = LocalContext.current + val coroutineScope = rememberCoroutineScope() + if (checkPermissions(context)) { + // Permissions are already granted. + LaunchedEffect(Unit) { + locationDisplay.dataSource.start() + } + } else { + RequestPermissions( + context = context, + onPermissionsGranted = { + coroutineScope.launch { + locationDisplay.dataSource.start() + } + } + ) + } + + Column(modifier = modifier.fillMaxSize() + .padding(top = 16.dp, start = 16.dp, end = 16.dp, bottom = 16.dp), + verticalArrangement = Arrangement.Top, + horizontalAlignment = Alignment.CenterHorizontally) { + OutlinedTextField( + modifier = Modifier.fillMaxWidth(), + value = beschreibungTextFieldValue.value, + onValueChange = { + beschreibungTextFieldValue.value = it + }, + minLines = 5, + label = { Text("Beschreibung")} + ) + DropDownMenuBox( + modifier = Modifier + .padding(8.dp), + textFieldLabel = "Select damage type", + textFieldValue = currentDamageType.value, + dropDownItemList = mapViewModel.damageTypeList, + onIndexSelected = { index -> + currentDamageType.value = mapViewModel.damageTypeList[index] + Log.d("CreatePage", "Selected index: $index") + } + ) + Row(modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceEvenly){ + Button(onClick = {}){ + Text("GPS") + } + Button(onClick = { + showModalBottomSheet.value = !showModalBottomSheet.value + }){ + Text("Karte") + } + } + } + if(showModalBottomSheet.value) { + ModalBottomSheet( + onDismissRequest = { + showModalBottomSheet.value = false + } + ) { + MapView( + modifier = Modifier, + arcGISMap = mapViewModel.map, + locationDisplay = locationDisplay, + mapViewProxy = mapViewModel.mapViewProxy, + onSingleTapConfirmed = mapViewModel::onTap, + ) + } + } + } \ No newline at end of file diff --git a/app/src/main/java/de/jadehs/strassenschadenpro2/pages/MapPage.kt b/app/src/main/java/de/jadehs/strassenschadenpro2/pages/MapPage.kt index 96d11d3..2a0de87 100644 --- a/app/src/main/java/de/jadehs/strassenschadenpro2/pages/MapPage.kt +++ b/app/src/main/java/de/jadehs/strassenschadenpro2/pages/MapPage.kt @@ -40,7 +40,7 @@ import de.jadehs.strassenschadenpro2.components.DropDownMenuBox import kotlinx.coroutines.launch @Composable -fun MapPage(modifier: Modifier = Modifier, application: Application) { +fun MapPage(modifier: Modifier = Modifier, mapViewModel: MapViewModel) { val context = LocalContext.current val coroutineScope = rememberCoroutineScope() @@ -71,15 +71,15 @@ fun MapPage(modifier: Modifier = Modifier, application: Application) { ) } - val mapViewModel = remember { MapViewModel(application) } + Column( - modifier = Modifier + modifier = modifier .fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, ) { MapView( - modifier = Modifier.weight(80f), + modifier = Modifier.weight(90f), arcGISMap = mapViewModel.map, locationDisplay = locationDisplay, mapViewProxy = mapViewModel.mapViewProxy, @@ -118,7 +118,7 @@ fun MapPage(modifier: Modifier = Modifier, application: Application) { } } DropDownMenuBox( - modifier = Modifier.weight(20f).padding(end = 8.dp), + modifier = Modifier.weight(10f).padding(end = 8.dp), textFieldLabel = "Feature management operation", textFieldValue = mapViewModel.currentFeatureOperation.operationName, dropDownItemList = FeatureOperationType.entries.map { entry -> entry.operationName },