132 lines
4.2 KiB
Dart
132 lines
4.2 KiB
Dart
import 'package:dio/dio.dart';
|
|
import '../domain/project.dart';
|
|
import '../domain/project_task.dart';
|
|
import 'dart:convert';
|
|
import '../domain/project_task_comment.dart';
|
|
|
|
class ProjectRepository {
|
|
final Dio _dio;
|
|
|
|
ProjectRepository(this._dio);
|
|
|
|
Future<List<Project>> getProjects() async {
|
|
try {
|
|
final response = await _dio.get('/projects');
|
|
if (response.data == null) return [];
|
|
return (response.data as List).map((p) => Project.fromJson(p)).toList();
|
|
} on DioException catch (e) {
|
|
if (e.response?.statusCode == 404) {
|
|
throw Exception("Projects API endpoint not found. Please ensure the backend server is updated to the latest Docker image.");
|
|
}
|
|
throw Exception(e.message ?? 'Unknown error fetching projects');
|
|
}
|
|
}
|
|
|
|
Future<Project> createProject({
|
|
required String name,
|
|
String? description,
|
|
int? customerId,
|
|
double? budget,
|
|
}) async {
|
|
final response = await _dio.post('/projects', data: {
|
|
'name': name,
|
|
if (description != null) 'description': description,
|
|
if (customerId != null) 'customerId': customerId,
|
|
if (budget != null) 'budget': budget,
|
|
});
|
|
return Project.fromJson(response.data);
|
|
}
|
|
|
|
Future<Project> updateProject({
|
|
required int projectId,
|
|
String? name,
|
|
String? description,
|
|
int? customerId,
|
|
double? budget,
|
|
String? status,
|
|
}) async {
|
|
final response = await _dio.put('/projects/$projectId', data: {
|
|
if (name != null) 'name': name,
|
|
if (description != null) 'description': description,
|
|
if (customerId != null) 'customerId': customerId,
|
|
if (budget != null) 'budget': budget,
|
|
if (status != null) 'status': status,
|
|
});
|
|
return Project.fromJson(response.data);
|
|
}
|
|
|
|
Future<void> deleteProject(int projectId) async {
|
|
await _dio.delete('/projects/$projectId');
|
|
}
|
|
|
|
Future<List<ProjectTask>> getTasks(int projectId) async {
|
|
final response = await _dio.get('/projects/$projectId/tasks');
|
|
return (response.data as List).map((t) => ProjectTask.fromJson(t)).toList();
|
|
}
|
|
|
|
Future<ProjectTask> createTask({
|
|
required int projectId,
|
|
required String title,
|
|
String? description,
|
|
String? assigneeName,
|
|
int? assigneeUserId,
|
|
bool? isBillable,
|
|
double? hourlyRate,
|
|
}) async {
|
|
final response = await _dio.post('/projects/$projectId/tasks', data: {
|
|
'title': title,
|
|
if (description != null) 'description': description,
|
|
if (assigneeName != null) 'assigneeName': assigneeName,
|
|
if (assigneeUserId != null) 'assigneeUserId': assigneeUserId,
|
|
if (isBillable != null) 'isBillable': isBillable,
|
|
if (hourlyRate != null) 'hourlyRate': hourlyRate,
|
|
});
|
|
return ProjectTask.fromJson(response.data);
|
|
}
|
|
|
|
Future<ProjectTask> updateTask({
|
|
required int taskId,
|
|
String? title,
|
|
String? description,
|
|
String? assigneeName,
|
|
int? assigneeUserId,
|
|
String? status,
|
|
bool? isBillable,
|
|
double? hourlyRate,
|
|
double? hoursLogged,
|
|
}) async {
|
|
final response = await _dio.put('/projects/tasks/$taskId', data: {
|
|
if (title != null) 'title': title,
|
|
if (description != null) 'description': description,
|
|
if (assigneeName != null) 'assigneeName': assigneeName,
|
|
if (assigneeUserId != null) 'assigneeUserId': assigneeUserId,
|
|
if (status != null) 'status': status,
|
|
if (isBillable != null) 'isBillable': isBillable,
|
|
if (hourlyRate != null) 'hourlyRate': hourlyRate,
|
|
if (hoursLogged != null) 'hoursLogged': hoursLogged,
|
|
});
|
|
return ProjectTask.fromJson(response.data);
|
|
}
|
|
|
|
Future<void> deleteTask(int taskId) async {
|
|
await _dio.delete('/projects/tasks/$taskId');
|
|
}
|
|
Future<List<ProjectTaskComment>> getComments(int taskId) async {
|
|
final response = await _dio.get('/projects/tasks/$taskId/comments');
|
|
return (response.data as List).map((c) => ProjectTaskComment.fromJson(c)).toList();
|
|
}
|
|
|
|
Future<ProjectTaskComment> addComment({
|
|
required int taskId,
|
|
required String content,
|
|
List<String>? imagesBase64,
|
|
}) async {
|
|
final response = await _dio.post('/projects/tasks/$taskId/comments', data: {
|
|
'content': content,
|
|
if (imagesBase64 != null && imagesBase64.isNotEmpty)
|
|
'imagesJson': jsonEncode(imagesBase64),
|
|
});
|
|
return ProjectTaskComment.fromJson(response.data);
|
|
}
|
|
}
|