import 'package:social_app/core/api/i_api_client.dart'; class TodoApi { final IApiClient _client; static const _prefix = '/api/v1/todos'; TodoApi(this._client); Future> getTodos({String? status, int? priority}) async { final queryParts = []; if (status != null) queryParts.add('status=$status'); if (priority != null) queryParts.add('priority=$priority'); final query = queryParts.isEmpty ? '' : '?${queryParts.join('&')}'; final response = await _client.get('$_prefix$query'); final List data = response.data; return data.map((json) => TodoResponse.fromJson(json)).toList(); } Future getTodo(String id) async { final response = await _client.get('$_prefix/$id'); return TodoResponse.fromJson(response.data); } Future createTodo({ required String title, String? description, DateTime? dueAt, int priority = 1, List scheduleItemIds = const [], }) async { final data = {'title': title, 'priority': priority}; if (description != null) data['description'] = description; if (dueAt != null) data['due_at'] = dueAt.toIso8601String(); if (scheduleItemIds.isNotEmpty) data['schedule_item_ids'] = scheduleItemIds; final response = await _client.post(_prefix, data: data); return TodoResponse.fromJson(response.data); } Future updateTodo( String id, { String? title, String? description, DateTime? dueAt, int? priority, String? status, List? scheduleItemIds, }) async { final data = {}; if (title != null) data['title'] = title; if (description != null) data['description'] = description; if (dueAt != null) data['due_at'] = dueAt.toIso8601String(); if (priority != null) data['priority'] = priority; if (status != null) data['status'] = status; if (scheduleItemIds != null) data['schedule_item_ids'] = scheduleItemIds; final response = await _client.patch('$_prefix/$id', data: data); return TodoResponse.fromJson(response.data); } Future completeTodo(String id) async { final response = await _client.post('$_prefix/$id/complete', data: {}); return TodoResponse.fromJson(response.data); } Future deleteTodo(String id) async { await _client.delete('$_prefix/$id'); } } class ScheduleItemBasic { final String id; final String title; final DateTime startAt; final DateTime? endAt; ScheduleItemBasic({ required this.id, required this.title, required this.startAt, this.endAt, }); factory ScheduleItemBasic.fromJson(Map json) { return ScheduleItemBasic( id: json['id'] as String, title: json['title'] as String, startAt: DateTime.parse(json['start_at'] as String), endAt: json['end_at'] != null ? DateTime.parse(json['end_at'] as String) : null, ); } } class TodoResponse { final String id; final String ownerId; final String title; final String? description; final DateTime? dueAt; final int priority; final String status; final DateTime? completedAt; final DateTime createdAt; final DateTime updatedAt; final List scheduleItems; TodoResponse({ required this.id, required this.ownerId, required this.title, this.description, this.dueAt, required this.priority, required this.status, this.completedAt, required this.createdAt, required this.updatedAt, this.scheduleItems = const [], }); factory TodoResponse.fromJson(Map json) { final scheduleItemsList = json['schedule_items'] as List? ?? []; return TodoResponse( id: json['id'] as String, ownerId: json['owner_id'] as String, title: json['title'] as String, description: json['description'] as String?, dueAt: json['due_at'] != null ? DateTime.parse(json['due_at'] as String) : null, priority: json['priority'] as int, status: json['status'] as String, completedAt: json['completed_at'] != null ? DateTime.parse(json['completed_at'] as String) : null, createdAt: DateTime.parse(json['created_at'] as String), updatedAt: DateTime.parse(json['updated_at'] as String), scheduleItems: scheduleItemsList .map((e) => ScheduleItemBasic.fromJson(e as Map)) .toList(), ); } TodoResponse copyWith({ String? id, String? ownerId, String? title, String? description, DateTime? dueAt, int? priority, String? status, DateTime? completedAt, DateTime? createdAt, DateTime? updatedAt, List? scheduleItems, }) { return TodoResponse( id: id ?? this.id, ownerId: ownerId ?? this.ownerId, title: title ?? this.title, description: description ?? this.description, dueAt: dueAt ?? this.dueAt, priority: priority ?? this.priority, status: status ?? this.status, completedAt: completedAt ?? this.completedAt, createdAt: createdAt ?? this.createdAt, updatedAt: updatedAt ?? this.updatedAt, scheduleItems: scheduleItems ?? this.scheduleItems, ); } }