diff --git a/backend/routes/todos.js b/backend/routes/todos.js index 2a1a028..1bcf37f 100644 --- a/backend/routes/todos.js +++ b/backend/routes/todos.js @@ -36,18 +36,24 @@ router.get("/", async (req, res) => { router.get("/today", async (req, res) => { try { - const { start } = getDayRange(); - // Show incomplete todos that are: - // 1. Due today or later (not overdue) - // 2. Have no due date set + const { start, end } = getDayRange(); + // Show todos that are: + // 1. Due today (between start and end of today) - both completed and incomplete + // 2. Due in the future (not yet due) - only incomplete + // 3. Have no due date set - only incomplete + // Filter out: overdue todos (due date before today) const todos = await Todo.find({ - completed: false, $or: [ - { dueDate: { $gte: start } }, - { dueDate: { $exists: false } }, - { dueDate: null } + // Today's todos (completed or not) - show with strikethrough if completed + { dueDate: { $gte: start, $lte: end } }, + // Future todos - only incomplete + { dueDate: { $gt: end }, completed: false }, + // No due date - only incomplete + { dueDate: { $exists: false }, completed: false }, + { dueDate: null, completed: false } ] }).sort({ + completed: 1, // Incomplete first dueDate: 1, createdAt: -1, }); diff --git a/flutter_app/lib/services/todo_service.dart b/flutter_app/lib/services/todo_service.dart index aabccfd..825ca7f 100644 --- a/flutter_app/lib/services/todo_service.dart +++ b/flutter_app/lib/services/todo_service.dart @@ -22,23 +22,39 @@ class TodoService { if (ApiConfig.useMockData) { // Using device's local timezone (should be Asia/Seoul for Korean users) final now = DateTime.now(); - final today = DateTime(now.year, now.month, now.day); - final tomorrow = today.add(const Duration(days: 1)); + final startOfToday = DateTime(now.year, now.month, now.day); + final endOfToday = DateTime(now.year, now.month, now.day, 23, 59, 59, 999); - return MockDataStore.todos.where((todo) { - if (todo.completed) { - // If completed, only show if it was due today - if (todo.dueDate == null) return false; - return todo.dueDate!.isAfter(today.subtract(const Duration(milliseconds: 1))) && - todo.dueDate!.isBefore(tomorrow); + final filtered = MockDataStore.todos.where((todo) { + if (todo.dueDate != null) { + // Due today - show regardless of completion status + if (todo.dueDate!.isAfter(startOfToday.subtract(const Duration(milliseconds: 1))) && + todo.dueDate!.isBefore(endOfToday.add(const Duration(milliseconds: 1)))) { + return true; + } + // Overdue (before today) - filter out + if (todo.dueDate!.isBefore(startOfToday)) { + return false; + } + // Future date - only show if incomplete + return !todo.completed; } - - // If not completed: - // 1. No due date -> show - // 2. Due today or before -> show - if (todo.dueDate == null) return true; - return todo.dueDate!.isBefore(tomorrow); + // No due date - only show if incomplete + return !todo.completed; }).toList(); + + // Sort: incomplete first, then by due date + filtered.sort((a, b) { + if (a.completed != b.completed) { + return a.completed ? 1 : -1; + } + if (a.dueDate == null && b.dueDate == null) return 0; + if (a.dueDate == null) return 1; + if (b.dueDate == null) return -1; + return a.dueDate!.compareTo(b.dueDate!); + }); + + return filtered; } final data = await _client.getList("${ApiConfig.todos}/today"); return data