feat: [#6] navigation principale (NavigationDrawer, NavHost, routes, DrawerViewModel)

This commit is contained in:
2026-06-06 06:03:53 +02:00
parent 4dfc224eb6
commit 38b96c0c72
7 changed files with 311 additions and 1 deletions
@@ -0,0 +1,141 @@
package com.planify.mobile.ui
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.FolderOpen
import androidx.compose.material.icons.outlined.Inbox
import androidx.compose.material.icons.outlined.Menu
import androidx.compose.material.icons.outlined.Settings
import androidx.compose.material.icons.outlined.Today
import androidx.compose.material3.DrawerValue
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.material3.NavigationDrawerItem
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.rememberDrawerState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.planify.mobile.ui.navigation.DrawerViewModel
import com.planify.mobile.ui.navigation.PlanifyNavHost
import com.planify.mobile.ui.navigation.Route
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen(viewModel: DrawerViewModel = hiltViewModel()) {
val navController = rememberNavController()
val drawerState = rememberDrawerState(DrawerValue.Closed)
val scope = rememberCoroutineScope()
val projects by viewModel.projects.collectAsState()
val navBackStack by navController.currentBackStackEntryAsState()
val currentRoute = navBackStack?.destination?.route
val drawerTitles = mapOf(
Route.Inbox.path to "Inbox",
Route.Today.path to "Aujourd'hui",
Route.Scheduled.path to "Planifié",
)
val title = drawerTitles[currentRoute]
?: projects.find { "project/${it.id}" == currentRoute }?.name
?: "Planify"
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
ModalDrawerSheet {
Text(
text = "Planify",
fontWeight = FontWeight.Bold,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 20.dp),
)
NavigationDrawerItem(
icon = { Icon(Icons.Outlined.Inbox, null) },
label = { Text("Inbox") },
selected = currentRoute == Route.Inbox.path,
onClick = {
navController.navigate(Route.Inbox.path)
scope.launch { drawerState.close() }
},
)
NavigationDrawerItem(
icon = { Icon(Icons.Outlined.Today, null) },
label = { Text("Aujourd'hui") },
selected = currentRoute == Route.Today.path,
onClick = {
navController.navigate(Route.Today.path)
scope.launch { drawerState.close() }
},
)
HorizontalDivider(Modifier.padding(vertical = 8.dp))
Text(
text = "Projets",
fontWeight = FontWeight.SemiBold,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp),
)
LazyColumn {
items(projects) { project ->
NavigationDrawerItem(
icon = { Icon(Icons.Default.FolderOpen, null) },
label = { Text(project.name) },
selected = currentRoute == "project/${project.id}",
onClick = {
navController.navigate(Route.Project().buildRoute(project.id))
scope.launch { drawerState.close() }
},
)
}
}
HorizontalDivider(Modifier.padding(vertical = 8.dp))
NavigationDrawerItem(
icon = { Icon(Icons.Outlined.Settings, null) },
label = { Text("Paramètres") },
selected = false,
onClick = { scope.launch { drawerState.close() } },
)
Spacer(Modifier.height(8.dp))
}
}
) {
Scaffold(
topBar = {
TopAppBar(
title = { Text(title) },
navigationIcon = {
IconButton(onClick = { scope.launch { drawerState.open() } }) {
Icon(Icons.Outlined.Menu, contentDescription = "Menu")
}
},
)
},
) { padding ->
PlanifyNavHost(
navController = navController,
modifier = Modifier.padding(padding),
)
}
}
}