diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b2a04b2..208634e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -53,6 +53,7 @@ dependencies { implementation(libs.androidx.ui.graphics) implementation(libs.androidx.ui.tooling.preview) implementation(libs.androidx.material3) + implementation(libs.androidx.material.icons.extended) // Hilt implementation(libs.hilt.android) diff --git a/app/src/main/java/de/krisenvorrat/app/MainActivity.kt b/app/src/main/java/de/krisenvorrat/app/MainActivity.kt index 89a68c6..af19290 100644 --- a/app/src/main/java/de/krisenvorrat/app/MainActivity.kt +++ b/app/src/main/java/de/krisenvorrat/app/MainActivity.kt @@ -8,9 +8,8 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview -import androidx.navigation.compose.rememberNavController import dagger.hilt.android.AndroidEntryPoint -import de.krisenvorrat.app.ui.navigation.KrisenvorratNavGraph +import de.krisenvorrat.app.ui.MainScreen import de.krisenvorrat.app.ui.theme.KrisenvorratTheme @AndroidEntryPoint @@ -20,8 +19,7 @@ class MainActivity : ComponentActivity() { enableEdgeToEdge() setContent { KrisenvorratTheme { - val navController = rememberNavController() - KrisenvorratNavGraph(navController = navController) + MainScreen() } } } diff --git a/app/src/main/java/de/krisenvorrat/app/ui/MainScreen.kt b/app/src/main/java/de/krisenvorrat/app/ui/MainScreen.kt new file mode 100644 index 0000000..0946551 --- /dev/null +++ b/app/src/main/java/de/krisenvorrat/app/ui/MainScreen.kt @@ -0,0 +1,72 @@ +package de.krisenvorrat.app.ui + +import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Icon +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import androidx.navigation.NavDestination.Companion.hasRoute +import androidx.navigation.NavGraph.Companion.findStartDestination +import androidx.navigation.compose.currentBackStackEntryAsState +import androidx.navigation.compose.rememberNavController +import de.krisenvorrat.app.ui.navigation.KrisenvorratNavGraph +import de.krisenvorrat.app.ui.navigation.TopLevelDestination + +@Composable +internal fun MainScreen() { + val navController = rememberNavController() + val navBackStackEntry by navController.currentBackStackEntryAsState() + val currentDestination = navBackStackEntry?.destination + + val showBottomBar = TopLevelDestination.entries.any { topLevel -> + currentDestination?.hasRoute(topLevel.route::class) == true + } + + Scaffold( + bottomBar = { + if (showBottomBar) { + NavigationBar { + TopLevelDestination.entries.forEach { destination -> + val isSelected = currentDestination?.hasRoute(destination.route::class) == true + + NavigationBarItem( + selected = isSelected, + onClick = { + navController.navigate(destination.route) { + popUpTo(navController.graph.findStartDestination().id) { + saveState = true + } + launchSingleTop = true + restoreState = true + } + }, + icon = { + Icon( + imageVector = if (isSelected) { + destination.selectedIcon + } else { + destination.unselectedIcon + }, + contentDescription = destination.label + ) + }, + label = { Text(destination.label) } + ) + } + } + } + } + ) { innerPadding -> + KrisenvorratNavGraph( + navController = navController, + modifier = Modifier + .padding(innerPadding) + .consumeWindowInsets(innerPadding) + ) + } +} diff --git a/app/src/main/java/de/krisenvorrat/app/ui/dashboard/DashboardScreen.kt b/app/src/main/java/de/krisenvorrat/app/ui/dashboard/DashboardScreen.kt index ba5ca8f..b0eb364 100644 --- a/app/src/main/java/de/krisenvorrat/app/ui/dashboard/DashboardScreen.kt +++ b/app/src/main/java/de/krisenvorrat/app/ui/dashboard/DashboardScreen.kt @@ -10,16 +10,11 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.List import androidx.compose.material3.Card import androidx.compose.material3.CardDefaults import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api -import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable @@ -42,38 +37,23 @@ import kotlin.math.roundToInt @OptIn(ExperimentalMaterial3Api::class) @Composable internal fun DashboardScreen( - onNavigateToItems: () -> Unit, viewModel: DashboardViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() - Scaffold( - topBar = { - TopAppBar( - title = { Text("Dashboard") }, - actions = { - IconButton(onClick = onNavigateToItems) { - Icon( - imageVector = Icons.Default.List, - contentDescription = "Artikelliste" - ) - } - } - ) - } - ) { padding -> + Column(modifier = Modifier.fillMaxSize()) { + TopAppBar(title = { Text("Übersicht") }) + if (uiState.isLoading) { CircularProgressIndicator( modifier = Modifier .fillMaxSize() - .padding(padding) .padding(16.dp) ) } else { LazyColumn( modifier = Modifier .fillMaxSize() - .padding(padding) .padding(horizontal = 16.dp), verticalArrangement = Arrangement.spacedBy(12.dp) ) { diff --git a/app/src/main/java/de/krisenvorrat/app/ui/item/ItemListScreen.kt b/app/src/main/java/de/krisenvorrat/app/ui/item/ItemListScreen.kt index be8d6ac..9b44a94 100644 --- a/app/src/main/java/de/krisenvorrat/app/ui/item/ItemListScreen.kt +++ b/app/src/main/java/de/krisenvorrat/app/ui/item/ItemListScreen.kt @@ -49,7 +49,6 @@ internal fun ItemListScreen( onItemClick: (String) -> Unit, onCategoriesClick: () -> Unit, onLocationsClick: () -> Unit, - onDashboardClick: () -> Unit, viewModel: ItemListViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -70,13 +69,6 @@ internal fun ItemListScreen( expanded = isMenuExpanded, onDismissRequest = { isMenuExpanded = false } ) { - DropdownMenuItem( - text = { Text("Dashboard") }, - onClick = { - isMenuExpanded = false - onDashboardClick() - } - ) DropdownMenuItem( text = { Text("Kategorien") }, onClick = { diff --git a/app/src/main/java/de/krisenvorrat/app/ui/navigation/KrisenvorratNavGraph.kt b/app/src/main/java/de/krisenvorrat/app/ui/navigation/KrisenvorratNavGraph.kt index baade69..43fae88 100644 --- a/app/src/main/java/de/krisenvorrat/app/ui/navigation/KrisenvorratNavGraph.kt +++ b/app/src/main/java/de/krisenvorrat/app/ui/navigation/KrisenvorratNavGraph.kt @@ -1,6 +1,7 @@ package de.krisenvorrat.app.ui.navigation import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -9,19 +10,21 @@ import de.krisenvorrat.app.ui.dashboard.DashboardScreen import de.krisenvorrat.app.ui.item.ItemFormScreen import de.krisenvorrat.app.ui.item.ItemListScreen import de.krisenvorrat.app.ui.location.LocationListScreen +import de.krisenvorrat.app.ui.settings.SettingsScreen +import de.krisenvorrat.app.ui.warnings.WarningsScreen @Composable -internal fun KrisenvorratNavGraph(navController: NavHostController) { +internal fun KrisenvorratNavGraph( + navController: NavHostController, + modifier: Modifier = Modifier +) { NavHost( navController = navController, - startDestination = Screen.Dashboard + startDestination = Screen.Dashboard, + modifier = modifier ) { composable { - DashboardScreen( - onNavigateToItems = { - navController.navigate(Screen.ItemList) - } - ) + DashboardScreen() } composable { @@ -37,11 +40,6 @@ internal fun KrisenvorratNavGraph(navController: NavHostController) { }, onLocationsClick = { navController.navigate(Screen.LocationManagement) - }, - onDashboardClick = { - navController.navigate(Screen.Dashboard) { - popUpTo(Screen.Dashboard) { inclusive = true } - } } ) } @@ -69,5 +67,13 @@ internal fun KrisenvorratNavGraph(navController: NavHostController) { } ) } + + composable { + WarningsScreen() + } + + composable { + SettingsScreen() + } } } diff --git a/app/src/main/java/de/krisenvorrat/app/ui/navigation/Screen.kt b/app/src/main/java/de/krisenvorrat/app/ui/navigation/Screen.kt index 0230d9a..b95933a 100644 --- a/app/src/main/java/de/krisenvorrat/app/ui/navigation/Screen.kt +++ b/app/src/main/java/de/krisenvorrat/app/ui/navigation/Screen.kt @@ -19,4 +19,10 @@ internal sealed interface Screen { @Serializable data object LocationManagement : Screen + + @Serializable + data object Warnings : Screen + + @Serializable + data object Settings : Screen } diff --git a/app/src/main/java/de/krisenvorrat/app/ui/navigation/TopLevelDestination.kt b/app/src/main/java/de/krisenvorrat/app/ui/navigation/TopLevelDestination.kt new file mode 100644 index 0000000..bd070fe --- /dev/null +++ b/app/src/main/java/de/krisenvorrat/app/ui/navigation/TopLevelDestination.kt @@ -0,0 +1,43 @@ +package de.krisenvorrat.app.ui.navigation + +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Home +import androidx.compose.material.icons.filled.Settings +import androidx.compose.material.icons.filled.Warning +import androidx.compose.material.icons.outlined.Home +import androidx.compose.material.icons.outlined.Inventory2 +import androidx.compose.material.icons.outlined.Settings +import androidx.compose.material.icons.outlined.Warning +import androidx.compose.ui.graphics.vector.ImageVector + +internal enum class TopLevelDestination( + val route: Screen, + val selectedIcon: ImageVector, + val unselectedIcon: ImageVector, + val label: String +) { + OVERVIEW( + route = Screen.Dashboard, + selectedIcon = Icons.Filled.Home, + unselectedIcon = Icons.Outlined.Home, + label = "Übersicht" + ), + INVENTORY( + route = Screen.ItemList, + selectedIcon = Icons.Outlined.Inventory2, + unselectedIcon = Icons.Outlined.Inventory2, + label = "Inventur" + ), + WARNINGS( + route = Screen.Warnings, + selectedIcon = Icons.Filled.Warning, + unselectedIcon = Icons.Outlined.Warning, + label = "Warnungen" + ), + SETTINGS( + route = Screen.Settings, + selectedIcon = Icons.Filled.Settings, + unselectedIcon = Icons.Outlined.Settings, + label = "Einstellungen" + ); +} diff --git a/app/src/main/java/de/krisenvorrat/app/ui/settings/SettingsScreen.kt b/app/src/main/java/de/krisenvorrat/app/ui/settings/SettingsScreen.kt new file mode 100644 index 0000000..b13aa2f --- /dev/null +++ b/app/src/main/java/de/krisenvorrat/app/ui/settings/SettingsScreen.kt @@ -0,0 +1,34 @@ +package de.krisenvorrat.app.ui.settings + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +internal fun SettingsScreen() { + Column(modifier = Modifier.fillMaxSize()) { + TopAppBar(title = { Text("Einstellungen") }) + Box( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + contentAlignment = Alignment.Center + ) { + Text( + text = "Einstellungen werden in einem späteren Schritt implementiert.", + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } +} diff --git a/app/src/main/java/de/krisenvorrat/app/ui/warnings/WarningsScreen.kt b/app/src/main/java/de/krisenvorrat/app/ui/warnings/WarningsScreen.kt new file mode 100644 index 0000000..da8a2a1 --- /dev/null +++ b/app/src/main/java/de/krisenvorrat/app/ui/warnings/WarningsScreen.kt @@ -0,0 +1,34 @@ +package de.krisenvorrat.app.ui.warnings + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +internal fun WarningsScreen() { + Column(modifier = Modifier.fillMaxSize()) { + TopAppBar(title = { Text("Warnungen") }) + Box( + modifier = Modifier + .fillMaxSize() + .padding(16.dp), + contentAlignment = Alignment.Center + ) { + Text( + text = "Warnungen werden in einem späteren Schritt implementiert.", + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurfaceVariant + ) + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f574afc..7a54881 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -32,6 +32,7 @@ androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-toolin androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" } hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } hilt-android-compiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" } androidx-hilt-navigation-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigationCompose" }