feat: [#22] vue Scheduled (tâches planifiées groupées par date : aujourd'hui, demain, cette semaine, plus tard)
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
package com.planify.mobile.ui.scheduled
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
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.outlined.CalendarMonth
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import com.planify.mobile.domain.model.Task
|
||||
import com.planify.mobile.ui.components.EmptyState
|
||||
import com.planify.mobile.ui.components.TaskRow
|
||||
|
||||
@Composable
|
||||
fun ScheduledScreen(
|
||||
onTaskClick: (Task) -> Unit,
|
||||
viewModel: ScheduledViewModel = hiltViewModel(),
|
||||
) {
|
||||
val groups by viewModel.groups.collectAsState()
|
||||
|
||||
if (groups.isEmpty()) {
|
||||
EmptyState(
|
||||
icon = Icons.Outlined.CalendarMonth,
|
||||
title = "Aucune tâche planifiée",
|
||||
subtitle = "Les tâches avec une date d'échéance apparaîtront ici",
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
LazyColumn(modifier = Modifier.fillMaxSize()) {
|
||||
groups.forEach { group ->
|
||||
item(key = group.label) {
|
||||
Text(
|
||||
text = group.label,
|
||||
style = MaterialTheme.typography.titleSmall,
|
||||
color = MaterialTheme.colorScheme.primary,
|
||||
modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
|
||||
)
|
||||
}
|
||||
items(group.tasks, key = { it.id }) { task ->
|
||||
TaskRow(
|
||||
task = task,
|
||||
onClick = { onTaskClick(task) },
|
||||
onCheckedChange = { viewModel.toggleTask(task) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.planify.mobile.ui.scheduled
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.planify.mobile.domain.model.Task
|
||||
import com.planify.mobile.domain.repository.TaskRepository
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import java.time.LocalDate
|
||||
import javax.inject.Inject
|
||||
|
||||
data class ScheduledGroup(val label: String, val tasks: List<Task>)
|
||||
|
||||
@HiltViewModel
|
||||
class ScheduledViewModel @Inject constructor(
|
||||
private val taskRepository: TaskRepository,
|
||||
) : ViewModel() {
|
||||
|
||||
val groups = taskRepository.getScheduledTasks()
|
||||
.map { tasks -> groupByDate(tasks) }
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), emptyList())
|
||||
|
||||
private fun groupByDate(tasks: List<Task>): List<ScheduledGroup> {
|
||||
val today = LocalDate.now()
|
||||
val tomorrow = today.plusDays(1)
|
||||
val endOfWeek = today.plusDays(7)
|
||||
|
||||
val buckets = linkedMapOf(
|
||||
"Aujourd'hui" to mutableListOf<Task>(),
|
||||
"Demain" to mutableListOf(),
|
||||
"Cette semaine" to mutableListOf(),
|
||||
"Plus tard" to mutableListOf(),
|
||||
)
|
||||
|
||||
for (task in tasks) {
|
||||
val date = runCatching { LocalDate.parse(task.dueDate?.date ?: "") }.getOrNull() ?: continue
|
||||
when {
|
||||
date == today -> buckets["Aujourd'hui"]!!.add(task)
|
||||
date == tomorrow -> buckets["Demain"]!!.add(task)
|
||||
date <= endOfWeek -> buckets["Cette semaine"]!!.add(task)
|
||||
else -> buckets["Plus tard"]!!.add(task)
|
||||
}
|
||||
}
|
||||
|
||||
return buckets.entries
|
||||
.filter { it.value.isNotEmpty() }
|
||||
.map { ScheduledGroup(it.key, it.value) }
|
||||
}
|
||||
|
||||
fun toggleTask(task: Task) {
|
||||
viewModelScope.launch { taskRepository.checkTask(task.id, !task.checked) }
|
||||
}
|
||||
|
||||
fun deleteTask(task: Task) {
|
||||
viewModelScope.launch { taskRepository.deleteTask(task.id) }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user