A prototype
This commit is contained in:
170
app/src/main/java/net/tinsae/clocked/MainActivity.kt
Normal file
170
app/src/main/java/net/tinsae/clocked/MainActivity.kt
Normal file
@@ -0,0 +1,170 @@
|
||||
package net.tinsae.clocked
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.WindowInsetsSides
|
||||
import androidx.compose.foundation.layout.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.only
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.safeDrawing
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.List
|
||||
import androidx.compose.material.icons.filled.AccountBox
|
||||
import androidx.compose.material.icons.filled.Home
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.adaptive.navigationsuite.NavigationSuiteScaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
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.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewScreenSizes
|
||||
import androidx.compose.ui.unit.dp
|
||||
import net.tinsae.clocked.dashboard.DashboardScreen
|
||||
import net.tinsae.clocked.history.HistoryScreen
|
||||
import net.tinsae.clocked.ui.theme.ClockedTheme
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enableEdgeToEdge()
|
||||
setContent {
|
||||
ClockedTheme {
|
||||
// The root of the app now decides whether to show Login or Main content
|
||||
AppEntry()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AppEntry() {
|
||||
// For now, we'll fake authentication. In a real app, this would come from a ViewModel or repository.
|
||||
var isAuthenticated by rememberSaveable { mutableStateOf(true) } // Start as not authenticated
|
||||
|
||||
if (isAuthenticated) {
|
||||
// If authenticated, show the main app UI
|
||||
ClockedApp()
|
||||
} else {
|
||||
// If not, show the Login screen
|
||||
LoginScreen(onLoginSuccess = { })
|
||||
}
|
||||
}
|
||||
|
||||
@PreviewScreenSizes
|
||||
@Composable
|
||||
fun ClockedApp() {
|
||||
var currentDestination by rememberSaveable { mutableStateOf(AppDestinations.HOME) }
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.fillMaxSize(), // Removed background for clarity
|
||||
topBar = {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
// Apply padding ONLY for the top safe area (status bar)
|
||||
.padding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top).asPaddingValues())
|
||||
.background(MaterialTheme.colorScheme.surface),
|
||||
contentAlignment = Alignment.CenterStart
|
||||
) {
|
||||
Text(
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp),
|
||||
text = stringResource(R.string.app_name),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
}
|
||||
},
|
||||
) { innerPadding -> // This padding from the parent Scaffold accounts for the TopBar.
|
||||
//val layoutDirection = LocalLayoutDirection.current
|
||||
val contentPadding = PaddingValues(
|
||||
// Respect the horizontal padding for gestures, etc.
|
||||
//start = innerPadding.calculateStartPadding(layoutDirection),
|
||||
//end = innerPadding.calculateEndPadding(layoutDirection),
|
||||
// Respect the top padding to stay below the top bar.
|
||||
top = innerPadding.calculateTopPadding(),
|
||||
// CRITICAL: Ignore the bottom padding from the parent Scaffold.
|
||||
bottom = 0.dp
|
||||
)
|
||||
|
||||
NavigationSuiteScaffold(
|
||||
// Apply our custom-calculated padding.
|
||||
modifier = Modifier.padding(contentPadding),
|
||||
navigationSuiteItems = {
|
||||
AppDestinations.entries.forEach {
|
||||
item(
|
||||
icon = { Icon(it.icon, contentDescription = it.label) },
|
||||
label = { Text(it.label) },
|
||||
selected = it == currentDestination,
|
||||
onClick = { currentDestination = it }
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
// The router now shows the correct screen based on the destination.
|
||||
when (currentDestination) {
|
||||
AppDestinations.HOME -> DashboardScreen(modifier = Modifier.fillMaxSize())
|
||||
AppDestinations.HISTORY -> HistoryScreen(modifier = Modifier.fillMaxSize())
|
||||
AppDestinations.PROFILE -> Greeting(name = "Profile", modifier = Modifier.fillMaxSize())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
enum class AppDestinations(
|
||||
val label: String,
|
||||
val icon: ImageVector,
|
||||
) {
|
||||
HOME("Home", Icons.Default.Home),
|
||||
HISTORY("History", Icons.AutoMirrored.Filled.List),
|
||||
PROFILE("Profile", Icons.Default.AccountBox),
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Greeting(name: String, modifier: Modifier = Modifier) {
|
||||
Scaffold(modifier = modifier) { innerPadding ->
|
||||
Text(
|
||||
text = "Hello $name!",
|
||||
modifier = Modifier.padding(innerPadding)
|
||||
)
|
||||
}
|
||||
}
|
||||
/*
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun GreetingPreview() {
|
||||
ClockedTheme {
|
||||
Greeting("Android")
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// --- PREVIEW THE ACTUAL APP ENTRY POINT ---
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun AppEntryPreview() {
|
||||
ClockedTheme {
|
||||
// This preview will correctly show the LoginScreen because isAuthenticated starts as false.
|
||||
AppEntry()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user