- 오늘 마감 할일은 완료해도 취소선으로 표시하며 유지 - 날짜가 지난 할일만 필터링하여 숨김 - 미완료 항목을 먼저 표시하도록 정렬 순서 변경 - 백엔드와 Flutter Mock 데이터 로직 동기화
106 lines
3.2 KiB
Dart
106 lines
3.2 KiB
Dart
import "../config/api_config.dart";
|
|
import "../models/todo_item.dart";
|
|
import "api_client.dart";
|
|
import "mock_data.dart";
|
|
|
|
class TodoService {
|
|
final ApiClient _client;
|
|
|
|
TodoService(this._client);
|
|
|
|
Future<List<TodoItem>> fetchTodos() async {
|
|
if (ApiConfig.useMockData) {
|
|
return List<TodoItem>.from(MockDataStore.todos);
|
|
}
|
|
final data = await _client.getList(ApiConfig.todos);
|
|
return data
|
|
.map((item) => TodoItem.fromJson(item as Map<String, dynamic>))
|
|
.toList();
|
|
}
|
|
|
|
Future<List<TodoItem>> fetchTodayTodos() async {
|
|
if (ApiConfig.useMockData) {
|
|
// Using device's local timezone (should be Asia/Seoul for Korean users)
|
|
final now = DateTime.now();
|
|
final startOfToday = DateTime(now.year, now.month, now.day);
|
|
final endOfToday = DateTime(now.year, now.month, now.day, 23, 59, 59, 999);
|
|
|
|
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;
|
|
}
|
|
// 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
|
|
.map((item) => TodoItem.fromJson(item as Map<String, dynamic>))
|
|
.toList();
|
|
}
|
|
|
|
Future<TodoItem> createTodo(TodoItem todo) async {
|
|
if (ApiConfig.useMockData) {
|
|
final created = TodoItem(
|
|
id: "todo-${DateTime.now().millisecondsSinceEpoch}",
|
|
familyMemberId: todo.familyMemberId,
|
|
title: todo.title,
|
|
completed: todo.completed,
|
|
dueDate: todo.dueDate,
|
|
);
|
|
MockDataStore.todos.add(created);
|
|
return created;
|
|
}
|
|
final data = await _client.post(ApiConfig.todos, todo.toJson());
|
|
return TodoItem.fromJson(data);
|
|
}
|
|
|
|
Future<TodoItem> updateTodo(TodoItem todo) async {
|
|
if (ApiConfig.useMockData) {
|
|
final index = MockDataStore.todos.indexWhere(
|
|
(item) => item.id == todo.id,
|
|
);
|
|
if (index != -1) {
|
|
MockDataStore.todos[index] = todo;
|
|
}
|
|
return todo;
|
|
}
|
|
final data = await _client.put(
|
|
"${ApiConfig.todos}/${todo.id}",
|
|
todo.toJson(),
|
|
);
|
|
return TodoItem.fromJson(data);
|
|
}
|
|
|
|
Future<void> deleteTodo(String id) async {
|
|
if (ApiConfig.useMockData) {
|
|
MockDataStore.todos.removeWhere((item) => item.id == id);
|
|
return;
|
|
}
|
|
await _client.delete("${ApiConfig.todos}/$id");
|
|
}
|
|
}
|