Skip to main content

Home Page

The HomeScreen.kt file defines the main screen displayed after a successful login. It provides a quick overview of the patient's recent activity, including:

  • the latest test (date and time),
  • the total number of tests completed,
  • recent questionnaire and configuration updates.

This screen also features:

  • a custom top bar with the app logo, the "Home" title, and a profile icon that links to the profile page,
  • action buttons to start a new test or fill out the latest questionnaire (conditionally enabled),
  • a bottom navigation bar to switch between all main screens of the app.

1 - Data loading and state preparation

Upon composition, the screen loads the most recent files and metadata from internal storage and SharedPreferences, including:

  • the most recent video file,
  • the most recent questionnaire file,
  • the latest configuration file,
  • the stored dates of last modifications (config and survey),
  • the questionnaireFilled state to determine if the survey can be retaken.
HomeScreen.kt
@Composable
fun HomePage(navController: NavHostController, patient: List<Patient>) {
val context = LocalContext.current

val videoDir = File(context.getExternalFilesDir(null), "EpilepsyTests/Videos")
val questionnaireDir = File(context.getExternalFilesDir(null), "EpilepsyTests/Questionnaires")
val configDir = context.filesDir

val latestVideo = videoDir.listFiles()?.maxByOrNull { it.lastModified() }
val totalTests = videoDir.listFiles { _, name ->
name.startsWith("Vidéo_") && name.endsWith(".mp4")
}?.size ?: 0

val lastQuestionnaire = questionnaireDir.listFiles()?.maxByOrNull { it.lastModified() }
val lastConfig = configDir.listFiles { _, name ->
name.startsWith("configuration_") && name.endsWith(".json")
}?.maxByOrNull { it.lastModified() }

val configDate = remember {
val prefs = context.getSharedPreferences("AppPrefsConfig", Context.MODE_PRIVATE)
val timestamp = prefs.getLong("lastConfigModification", -1L)
if (timestamp != -1L)
SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(Date(timestamp))
else "N/A"
}

val lastSurveyModDate = remember {
val prefs = context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
val timestamp = prefs.getLong("lastSurveyModification", -1L)
if (timestamp != -1L)
SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(Date(timestamp))
else "N/A"
}

val videoDate = latestVideo?.let {
SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(Date(it.lastModified()))
} ?: "N/A"

val videoTime = latestVideo?.let {
SimpleDateFormat("HH:mm", Locale.getDefault()).format(Date(it.lastModified()))
} ?: "N/A"

val questionnaireDate = lastQuestionnaire?.let {
SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(Date(it.lastModified()))
} ?: "N/A"

val isQuestionnaireFilled = remember {
context.getSharedPreferences("AppPrefs", Context.MODE_PRIVATE)
.getBoolean("questionnaireFilled", true)
}

...

2 - UI Structure and Layout

The UI is built using Box, Column, and themed Text elements for consistency. Cards display key data, and buttons enable user actions.

Top App Bar

A colored bar displays:

  • the logo,
  • the "Home" title,
  • a user icon leading to the profile screen.

Summary Cards

Three cards provide a snapshot of:

  1. Latest test (with date and time),
  2. Total number of tests recorded,
  3. Questionnaire and configuration details.

Actions

Two action buttons:

  • "Commencer un test" navigates to the test screen,
  • "Remplir questionnaire" is enabled only if the survey hasn't been completed.

Code extract: UI composition

HomeScreen.kt
AppTheme {
Box(
modifier = Modifier
.fillMaxSize()
.background(MaterialTheme.colorScheme.background)
.border(4.dp, Color(0xFF2B4765), RoundedCornerShape(1.dp))
) {
Column(
modifier = Modifier
.fillMaxSize()
.padding(bottom = 70.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
// Top bar with logo, title and profile
...
// Summary cards
...
// Action buttons
...
}

// Bottom navigation bar
NavigationBar(
navController = navController,
modifier = Modifier.align(Alignment.BottomCenter)
)
}
}

3 - Navigation Bar

At the bottom of the screen, a persistent navigation bar allows quick access to:

HomeScreen.kt
@Composable
fun NavigationBar(navController: NavHostController, modifier: Modifier = Modifier) {
Row(
modifier = modifier
.fillMaxWidth()
.height(70.dp)
.background(Color(0xFF2B4765)),
horizontalArrangement = Arrangement.SpaceEvenly,
verticalAlignment = Alignment.CenterVertically
) {
IconButton(onClick = { navController.navigate("home") }) {
Image(
painter = painterResource(id = R.mipmap.ic_home_foreground),
contentDescription = "Home",
modifier = Modifier.fillMaxHeight().aspectRatio(1f)
)
}
IconButton(onClick = { navController.navigate("demo/0") }) {
Image(
painter = painterResource(id = R.mipmap.ic_demo_foreground),
contentDescription = "Demo",
modifier = Modifier.fillMaxHeight().aspectRatio(1f)
)
}
IconButton(onClick = { navController.navigate("files") }) {
Image(
painter = painterResource(id = R.mipmap.ic_files_foreground),
contentDescription = "Files",
modifier = Modifier.fillMaxHeight().aspectRatio(1f)
)
}
IconButton(onClick = { navController.navigate("settings") }) {
Image(
painter = painterResource(id = R.mipmap.ic_settings_foreground),
contentDescription = "Settings",
modifier = Modifier.fillMaxHeight().aspectRatio(1f)
)
}
}
}

Summary

The HomeScreen.kt centralizes essential patient information and gives quick access to all app functionalities. It balances a clean UI layout with dynamic content loaded from local files and preferences, ensuring that the app always displays the latest patient data.