diff --git a/app/src/main/java/com/planify/mobile/ui/scheduled/ScheduledScreen.kt b/app/src/main/java/com/planify/mobile/ui/scheduled/ScheduledScreen.kt new file mode 100644 index 0000000..a6a083c --- /dev/null +++ b/app/src/main/java/com/planify/mobile/ui/scheduled/ScheduledScreen.kt @@ -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) }, + ) + } + } + } +} diff --git a/app/src/main/java/com/planify/mobile/ui/scheduled/ScheduledViewModel.kt b/app/src/main/java/com/planify/mobile/ui/scheduled/ScheduledViewModel.kt new file mode 100644 index 0000000..09b9d34 --- /dev/null +++ b/app/src/main/java/com/planify/mobile/ui/scheduled/ScheduledViewModel.kt @@ -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) + +@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): List { + val today = LocalDate.now() + val tomorrow = today.plusDays(1) + val endOfWeek = today.plusDays(7) + + val buckets = linkedMapOf( + "Aujourd'hui" to mutableListOf(), + "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) } + } +}