package dev.privacyllc.period.navigation import androidx.annotation.StringRes import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.CalendarMonth import androidx.compose.material.icons.filled.Insights import androidx.compose.material.icons.filled.Settings import androidx.compose.material.icons.filled.Today import androidx.compose.material.icons.filled.Circle import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme 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.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.navigation.NavDestination.Companion.hierarchy import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import dev.privacyllc.period.R import dev.privacyllc.period.designsystem.PeriodTheme import dev.privacyllc.period.feature.today.TodayScreen /** * The four tabs from docs/planning/PRODUCT_PLAN.md §20. * * Four and only four. Every proposal to add a fifth is answered by * docs/planning/PROJECT_PLAN.md's "deliberately not" list. */ enum class PeriodDestination( val route: String, @param:StringRes val labelRes: Int, val icon: ImageVector, ) { TODAY("today", R.string.tab_today, Icons.Filled.Today), CALENDAR("calendar", R.string.tab_calendar, Icons.Filled.CalendarMonth), INSIGHTS("insights", R.string.tab_insights, Icons.Filled.Insights), SETTINGS("settings", R.string.tab_settings, Icons.Filled.Settings), } @Composable fun PeriodApp() { val navController = rememberNavController() val backStackEntry by navController.currentBackStackEntryAsState() val currentDestination = backStackEntry?.destination Scaffold( bottomBar = { NavigationBar { PeriodDestination.entries.forEach { destination -> val selected = currentDestination?.hierarchy?.any { it.route == destination.route } == true NavigationBarItem( selected = selected, onClick = { navController.navigate(destination.route) { popUpTo(navController.graph.findStartDestination().id) { saveState = true } launchSingleTop = true restoreState = true } }, icon = { Icon(destination.icon, contentDescription = null) }, label = { Text(stringResource(destination.labelRes)) }, ) } } }, ) { innerPadding -> NavHost( navController = navController, startDestination = PeriodDestination.TODAY.route, modifier = Modifier.padding(innerPadding), ) { composable(PeriodDestination.TODAY.route) { TodayScreen() } // Calendar, Insights and Settings arrive in Batches 03 and 06. They // say "not built yet" rather than showing a convincing mock. PeriodDestination.entries .filter { it != PeriodDestination.TODAY } .forEach { destination -> composable(destination.route) { PlaceholderScreen(stringResource(destination.labelRes)) } } } } } /** * Skeleton only. Each of these is replaced by its real screen in Batch 03, and * saying "not built yet" on the screen is deliberate — a convincing mock is how * a screen comes to be believed finished. */ @Composable private fun PlaceholderScreen(title: String) { Column( modifier = Modifier.fillMaxSize(), verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally, ) { Icon( Icons.Filled.Circle, contentDescription = null, tint = MaterialTheme.colorScheme.primaryContainer, ) Text( text = title, style = MaterialTheme.typography.headlineMedium, color = MaterialTheme.colorScheme.onBackground, ) Text( text = "Not built yet", style = MaterialTheme.typography.bodyMedium, color = MaterialTheme.colorScheme.onSurfaceVariant, textAlign = TextAlign.Center, ) } } @Preview(showBackground = true) @Composable private fun PlaceholderPreview() { PeriodTheme { PlaceholderScreen("Calendar") } }