package com.example.snapandsolve import DamageFilterDialog import DamageListDialog import MapViewModel import android.app.Application import androidx.compose.foundation.layout.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.FilterAlt import androidx.compose.material.icons.filled.FormatListNumbered import androidx.compose.material.icons.filled.Menu import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp import applyDamageFilter import com.example.snapandsolve.camera.AlbumViewModel import com.example.snapandsolve.ui.theme.* import com.example.snapandsolve.ui.theme.composable.SideSlider import com.example.snapandsolve.ui.theme.composable.SliderMenuItem import com.example.snapandsolve.view.ReportDialog import getActiveFilters import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @Composable fun MainScreen(modifier: Modifier = Modifier, application: Application) { var showReport by rememberSaveable { mutableStateOf(false) } var sliderOpen by rememberSaveable { mutableStateOf(false) } val mapViewModel = remember { MapViewModel(application) } val albumViewModel = remember { AlbumViewModel(Dispatchers.Default) } fun openReport() { showReport = true sliderOpen = false } fun closeReport() { showReport = false } LaunchedEffect(mapViewModel.reopenReport) { if (mapViewModel.reopenReport) { showReport = true mapViewModel.consumeReopenReport() } } Scaffold( modifier = Modifier.fillMaxSize(), topBar = { AppTopBar() }, bottomBar = { BottomAppBar( modifier = Modifier.height(120.dp), containerColor = AppColor, ) { IconButton(onClick = { sliderOpen = !sliderOpen; showReport = false }) { Icon(Icons.Default.Menu, contentDescription = "Menu") } } }, floatingActionButton = { LargeFloatingActionButton( onClick = { mapViewModel.resetDraft() mapViewModel.closeFeatureInfo() openReport() }, modifier = Modifier.offset(y = 64.dp), containerColor = ButtonColor ) { Icon(Icons.Default.Add, contentDescription = "Add") } }, floatingActionButtonPosition = FabPosition.Center, ) { innerPadding -> ContentScreen( modifier = Modifier.padding(innerPadding), mapViewModel = mapViewModel, albumViewModel = albumViewModel, showReport = showReport, sliderOpen = sliderOpen, onDismissReport = ::closeReport ) } } @Composable fun ContentScreen( modifier: Modifier = Modifier, mapViewModel: MapViewModel, albumViewModel: AlbumViewModel, showReport: Boolean, sliderOpen: Boolean, onDismissReport: () -> Unit ) { val context = LocalContext.current val coroutineScope = rememberCoroutineScope() // NEU: State für Filter-Dialog var showFilterDialog by remember { mutableStateOf(false) } var showDamageList by remember { mutableStateOf(false) } Box(modifier = modifier.fillMaxSize()) { // Map MapSegment( modifier = Modifier.fillMaxSize(), mapViewModel = mapViewModel ) // Dialog if (showDamageList) { DamageListDialog( onDismiss = { showDamageList = false }, onDamageClick = { feature -> mapViewModel.selectedFeature = feature mapViewModel.showFeatureInfo = true }, mapViewModel = mapViewModel ) } // Report Overlay if (showReport) { ReportDialog( onCancel = onDismissReport, onClose = onDismissReport, viewModel = albumViewModel, mapViewModel = mapViewModel ) } // Feature Info Dialog if (mapViewModel.showFeatureInfo) { FeatureInfoDialog( feature = mapViewModel.selectedFeature, onDismiss = { mapViewModel.closeFeatureInfo() }, onRate = { feature, isPositive -> coroutineScope.launch { mapViewModel.updateFeatureRating(feature, isPositive, context) } } ) } // Filter Dialog - NEU! if (showFilterDialog) { DamageFilterDialog( damageTypes = MapViewModel.DAMAGE_TYPES, // <-- Nutzt zentrale Liste currentFilters = mapViewModel.getActiveFilters(), onDismiss = { showFilterDialog = false }, onApplyFilter = { selectedTypes, startDate, endDate -> coroutineScope.launch { mapViewModel.applyDamageFilter(selectedTypes, startDate, endDate) } } ) } // Side Slider SideSlider(visible = sliderOpen) { Text( "Menü", style = MaterialTheme.typography.titleMedium, modifier = Modifier.padding(bottom = 12.dp) ) SliderMenuItem( text = "Schäden filtern", icon = Icons.Default.FilterAlt, onClick = { showFilterDialog = true // <-- Öffnet Filter-Dialog } ) SliderMenuItem( text = "Schadensliste", icon = Icons.Default.FormatListNumbered, onClick = { showDamageList = true } ) } } } @OptIn(ExperimentalMaterial3Api::class) @Composable fun AppTopBar( modifier: Modifier = Modifier ) { MediumTopAppBar( title = { Text("Scan And Solve") }, colors = TopAppBarDefaults.mediumTopAppBarColors( containerColor = AppColor, titleContentColor = Color.White ) ) } /* suspend fun loadFirstAttachmentBitmap( feature: ArcGISFeature ): ImageBitmap? { // Feature muss geladen sein feature.load().getOrThrow() // Attachments abrufen val attachments = feature.fetchAttachments().getOrThrow() val first = attachments.firstOrNull() ?: return null // Attachment-Daten laden val data = first.fetchData().getOrThrow() val bitmap = BitmapFactory.decodeByteArray(data, 0, data.size) return bitmap.asImageBitmap() } */