class TaskComment { final int id; final int taskId; final int userId; final String username; final String body; final DateTime createdAt; const TaskComment({ required this.id, required this.taskId, required this.userId, required this.username, required this.body, required this.createdAt, }); factory TaskComment.fromJson(Map j) => TaskComment( id: j['id'], taskId: j['task_id'], userId: j['user_id'], username: j['username'] ?? '', body: j['body'] ?? '', createdAt: DateTime.parse(j['created_at']), ); } class Task { final int id; final String title; final String status; final DateTime? dueDate; final int? assignedTo; final String? assignedUsername; final int? parentId; final int createdBy; final String createdByUsername; final DateTime? completedAt; final DateTime createdAt; final int subtaskCount; final int commentCount; final List subtasks; final List comments; const Task({ required this.id, required this.title, required this.status, this.dueDate, this.assignedTo, this.assignedUsername, this.parentId, required this.createdBy, required this.createdByUsername, this.completedAt, required this.createdAt, this.subtaskCount = 0, this.commentCount = 0, this.subtasks = const [], this.comments = const [], }); factory Task.fromJson(Map j) => Task( id: j['id'], title: j['title'] ?? '', status: j['status'] ?? 'todo', dueDate: j['due_date'] != null ? DateTime.tryParse(j['due_date']) : null, assignedTo: j['assigned_to'], assignedUsername: j['assigned_username'], parentId: j['parent_id'], createdBy: j['created_by'] ?? 0, createdByUsername: j['created_by_username'] ?? '', completedAt: j['completed_at'] != null ? DateTime.tryParse(j['completed_at']) : null, createdAt: DateTime.parse(j['created_at']), subtaskCount: j['subtask_count'] ?? 0, commentCount: j['comment_count'] ?? 0, subtasks: (j['subtasks'] as List? ?? []) .map((e) => Task.fromJson(e as Map)) .toList(), comments: (j['comments'] as List? ?? []) .map((e) => TaskComment.fromJson(e as Map)) .toList(), ); bool get isDone => status == 'done'; bool get isOverdue => dueDate != null && dueDate!.isBefore(DateTime.now()) && !isDone; } class PagedTasks { final List items; final int total; final int page; final int limit; const PagedTasks({required this.items, required this.total, required this.page, required this.limit}); factory PagedTasks.fromJson(Map j) => PagedTasks( items: (j['items'] as List).map((e) => Task.fromJson(e)).toList(), total: j['total'], page: j['page'], limit: j['limit'], ); }