feat: 오늘의 할일 완료 항목 표시 개선

- 오늘 마감 할일은 완료해도 취소선으로 표시하며 유지
- 날짜가 지난 할일만 필터링하여 숨김
- 미완료 항목을 먼저 표시하도록 정렬 순서 변경
- 백엔드와 Flutter Mock 데이터 로직 동기화
This commit is contained in:
kihong.kim
2026-02-01 01:35:17 +09:00
parent 32e67bfcc2
commit fdf2287c4b
2 changed files with 44 additions and 22 deletions

View File

@@ -36,18 +36,24 @@ router.get("/", async (req, res) => {
router.get("/today", async (req, res) => { router.get("/today", async (req, res) => {
try { try {
const { start } = getDayRange(); const { start, end } = getDayRange();
// Show incomplete todos that are: // Show todos that are:
// 1. Due today or later (not overdue) // 1. Due today (between start and end of today) - both completed and incomplete
// 2. Have no due date set // 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({ const todos = await Todo.find({
completed: false,
$or: [ $or: [
{ dueDate: { $gte: start } }, // Today's todos (completed or not) - show with strikethrough if completed
{ dueDate: { $exists: false } }, { dueDate: { $gte: start, $lte: end } },
{ dueDate: null } // Future todos - only incomplete
{ dueDate: { $gt: end }, completed: false },
// No due date - only incomplete
{ dueDate: { $exists: false }, completed: false },
{ dueDate: null, completed: false }
] ]
}).sort({ }).sort({
completed: 1, // Incomplete first
dueDate: 1, dueDate: 1,
createdAt: -1, createdAt: -1,
}); });

View File

@@ -22,23 +22,39 @@ class TodoService {
if (ApiConfig.useMockData) { if (ApiConfig.useMockData) {
// Using device's local timezone (should be Asia/Seoul for Korean users) // Using device's local timezone (should be Asia/Seoul for Korean users)
final now = DateTime.now(); final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day); final startOfToday = DateTime(now.year, now.month, now.day);
final tomorrow = today.add(const Duration(days: 1)); final endOfToday = DateTime(now.year, now.month, now.day, 23, 59, 59, 999);
return MockDataStore.todos.where((todo) { final filtered = MockDataStore.todos.where((todo) {
if (todo.completed) { if (todo.dueDate != null) {
// If completed, only show if it was due today // Due today - show regardless of completion status
if (todo.dueDate == null) return false; if (todo.dueDate!.isAfter(startOfToday.subtract(const Duration(milliseconds: 1))) &&
return todo.dueDate!.isAfter(today.subtract(const Duration(milliseconds: 1))) && todo.dueDate!.isBefore(endOfToday.add(const Duration(milliseconds: 1)))) {
todo.dueDate!.isBefore(tomorrow); return true;
} }
// Overdue (before today) - filter out
// If not completed: if (todo.dueDate!.isBefore(startOfToday)) {
// 1. No due date -> show return false;
// 2. Due today or before -> show }
if (todo.dueDate == null) return true; // Future date - only show if incomplete
return todo.dueDate!.isBefore(tomorrow); return !todo.completed;
}
// No due date - only show if incomplete
return !todo.completed;
}).toList(); }).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"); final data = await _client.getList("${ApiConfig.todos}/today");
return data return data