Skip to content

Commit 118a3ba

Browse files
authored
Merge pull request #21 from CoderJava/feature/buat-fitur-manual-track
Feature - Buat add manual track
2 parents a3ce663 + 3176434 commit 118a3ba

File tree

36 files changed

+2146
-125
lines changed

36 files changed

+2146
-125
lines changed

assets/translations/en-US.json

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,5 +246,24 @@
246246
"new_password": "New Password",
247247
"subtitle_new_password": "Please create a new password that you don't use on any other site",
248248
"change": "Change",
249-
"create_new_password": "Create new password"
249+
"create_new_password": "Create new password",
250+
"add_manual_track_successfully": "Add manual track successfully",
251+
"add_manual_track": "Add Manual Track",
252+
"project": "Project",
253+
"select_project": "Select project",
254+
"task": "Task",
255+
"select_task": "Select task",
256+
"select_a_project_first": "Select a project first",
257+
"no_data_available": "No data available",
258+
"please_choose_a_task": "Please choose a task",
259+
"start_time": "Start time",
260+
"set_start_time": "Set start time",
261+
"time": "Time",
262+
"date": "Date",
263+
"finish_time": "Finish time",
264+
"set_finish_time": "Set finish time",
265+
"set_start_and_finish_time": "Set start and finish time",
266+
"duration": "Duration",
267+
"please_set_start_time": "Please set start time",
268+
"please_set_finish_time": "Please set finish time"
250269
}

lib/feature/data/datasource/project/project_remote_data_source.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'package:dio/dio.dart';
22
import 'package:dipantau_desktop_client/config/base_url_config.dart';
33
import 'package:dipantau_desktop_client/config/flavor_config.dart';
44
import 'package:dipantau_desktop_client/feature/data/model/project/project_response.dart';
5+
import 'package:dipantau_desktop_client/feature/data/model/project_task/project_task_response.dart';
56

67
abstract class ProjectRemoteDataSource {
78
/// Panggil endpoint [host]/project/user/:id
@@ -12,6 +13,15 @@ abstract class ProjectRemoteDataSource {
1213
late String pathGetProject;
1314

1415
Future<ProjectResponse> getProject(String userId);
16+
17+
/// Panggil endpoint [host]/project/user/:id/detail
18+
/// path parameter
19+
/// id - nilai ID user
20+
///
21+
/// Throws [DioException] untuk semua error kode
22+
late String pathGetProjectTaskByUserId;
23+
24+
Future<ProjectTaskResponse> getProjectTaskByUserId(String userId);
1525
}
1626

1727
class ProjectRemoteDataSourceImpl implements ProjectRemoteDataSource {
@@ -44,4 +54,25 @@ class ProjectRemoteDataSourceImpl implements ProjectRemoteDataSource {
4454
throw DioException(requestOptions: RequestOptions(path: pathGetProject));
4555
}
4656
}
57+
58+
@override
59+
String pathGetProjectTaskByUserId = '';
60+
61+
@override
62+
Future<ProjectTaskResponse> getProjectTaskByUserId(String userId) async {
63+
pathGetProjectTaskByUserId = '$baseUrl/user/$userId/detail';
64+
final response = await dio.get(
65+
pathGetProjectTaskByUserId,
66+
options: Options(
67+
headers: {
68+
baseUrlConfig.requiredToken: true,
69+
},
70+
),
71+
);
72+
if (response.statusCode.toString().startsWith('2')) {
73+
return ProjectTaskResponse.fromJson(response.data);
74+
} else {
75+
throw DioException(requestOptions: RequestOptions(path: pathGetProjectTaskByUserId));
76+
}
77+
}
4778
}

lib/feature/data/datasource/track/track_remote_data_source.dart

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_cre
55
import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_create_track_image_body.dart';
66
import 'package:dipantau_desktop_client/feature/data/model/create_track/create_track_body.dart';
77
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';
8+
import 'package:dipantau_desktop_client/feature/data/model/manual_create_track/manual_create_track_body.dart';
89
import 'package:dipantau_desktop_client/feature/data/model/track_user/track_user_response.dart';
910
import 'package:dipantau_desktop_client/feature/data/model/track_user_lite/track_user_lite_response.dart';
1011

@@ -50,6 +51,13 @@ abstract class TrackRemoteDataSource {
5051
late String pathDeleteTrack;
5152

5253
Future<GeneralResponse> deleteTrackUser(int trackId);
54+
55+
/// Panggil endpoint [host]/track/manual
56+
///
57+
/// Throws [DioException] untuk semua error kode
58+
late String pathCreateManualTrack;
59+
60+
Future<GeneralResponse> createManualTrack(ManualCreateTrackBody body);
5361
}
5462

5563
class TrackRemoteDataSourceImpl implements TrackRemoteDataSource {
@@ -222,4 +230,26 @@ class TrackRemoteDataSourceImpl implements TrackRemoteDataSource {
222230
throw DioException(requestOptions: RequestOptions(path: pathDeleteTrack));
223231
}
224232
}
233+
234+
@override
235+
String pathCreateManualTrack = '';
236+
237+
@override
238+
Future<GeneralResponse> createManualTrack(ManualCreateTrackBody body) async {
239+
pathCreateManualTrack = '$baseUrl/manual';
240+
final response = await dio.post(
241+
pathCreateManualTrack,
242+
data: body.toJson(),
243+
options: Options(
244+
headers: {
245+
baseUrlConfig.requiredToken: true,
246+
},
247+
),
248+
);
249+
if (response.statusCode.toString().startsWith('2')) {
250+
return GeneralResponse.fromJson(response.data);
251+
} else {
252+
throw DioException(requestOptions: RequestOptions(path: pathCreateManualTrack));
253+
}
254+
}
225255
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:json_annotation/json_annotation.dart';
3+
4+
part 'manual_create_track_body.g.dart';
5+
6+
@JsonSerializable()
7+
class ManualCreateTrackBody extends Equatable {
8+
@JsonKey(name: 'task_id')
9+
final int taskId;
10+
@JsonKey(name: 'start_date')
11+
final String startDate;
12+
@JsonKey(name: 'finish_date')
13+
final String finishDate;
14+
@JsonKey(name: 'duration')
15+
final int duration;
16+
17+
ManualCreateTrackBody({
18+
required this.taskId,
19+
required this.startDate,
20+
required this.finishDate,
21+
required this.duration,
22+
});
23+
24+
factory ManualCreateTrackBody.fromJson(Map<String, dynamic> json) => _$ManualCreateTrackBodyFromJson(json);
25+
26+
Map<String, dynamic> toJson() => _$ManualCreateTrackBodyToJson(this);
27+
28+
@override
29+
List<Object?> get props => [
30+
taskId,
31+
startDate,
32+
finishDate,
33+
duration,
34+
];
35+
36+
@override
37+
String toString() {
38+
return 'ManualCreateTrackBody{taskId: $taskId, startDate: $startDate, finishDate: $finishDate, duration: $duration}';
39+
}
40+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:json_annotation/json_annotation.dart';
3+
4+
part 'project_task_response.g.dart';
5+
6+
@JsonSerializable()
7+
class ProjectTaskResponse extends Equatable {
8+
@JsonKey(name: 'data')
9+
final List<ItemProjectTaskResponse>? data;
10+
11+
ProjectTaskResponse({
12+
required this.data,
13+
});
14+
15+
factory ProjectTaskResponse.fromJson(Map<String, dynamic> json) => _$ProjectTaskResponseFromJson(json);
16+
17+
Map<String, dynamic> toJson() => _$ProjectTaskResponseToJson(this);
18+
19+
@override
20+
List<Object?> get props => [
21+
data,
22+
];
23+
24+
@override
25+
String toString() {
26+
return 'ProjectTaskResponse{data: $data}';
27+
}
28+
}
29+
30+
@JsonSerializable()
31+
class ItemProjectTaskResponse extends Equatable {
32+
@JsonKey(name: 'project_id')
33+
final int? projectId;
34+
@JsonKey(name: 'project_name')
35+
final String? projectName;
36+
@JsonKey(name: 'tasks')
37+
final List<ItemTaskLiteProjectTaskResponse> tasks;
38+
39+
ItemProjectTaskResponse({
40+
required this.projectId,
41+
required this.projectName,
42+
required this.tasks,
43+
});
44+
45+
factory ItemProjectTaskResponse.fromJson(Map<String, dynamic> json) => _$ItemProjectTaskResponseFromJson(json);
46+
47+
Map<String, dynamic> toJson() => _$ItemProjectTaskResponseToJson(this);
48+
49+
@override
50+
List<Object?> get props => [
51+
projectId,
52+
projectName,
53+
tasks,
54+
];
55+
56+
@override
57+
String toString() {
58+
return 'ItemProjectTaskResponse{projectId: $projectId, projectName: $projectName, tasks: $tasks}';
59+
}
60+
}
61+
62+
@JsonSerializable()
63+
class ItemTaskLiteProjectTaskResponse extends Equatable {
64+
@JsonKey(name: 'id')
65+
final int? id;
66+
@JsonKey(name: 'name')
67+
final String? name;
68+
69+
ItemTaskLiteProjectTaskResponse({
70+
required this.id,
71+
required this.name,
72+
});
73+
74+
factory ItemTaskLiteProjectTaskResponse.fromJson(Map<String, dynamic> json) =>
75+
_$ItemTaskLiteProjectTaskResponseFromJson(json);
76+
77+
Map<String, dynamic> toJson() => _$ItemTaskLiteProjectTaskResponseToJson(this);
78+
79+
@override
80+
List<Object?> get props => [
81+
id,
82+
name,
83+
];
84+
85+
@override
86+
String toString() {
87+
return 'ItemTaskLiteProjectTaskResponse{id: $id, name: $name}';
88+
}
89+
}

lib/feature/data/repository/project/project_repository_impl.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:dipantau_desktop_client/core/error/failure.dart';
44
import 'package:dipantau_desktop_client/core/network/network_info.dart';
55
import 'package:dipantau_desktop_client/feature/data/datasource/project/project_remote_data_source.dart';
66
import 'package:dipantau_desktop_client/feature/data/model/project/project_response.dart';
7+
import 'package:dipantau_desktop_client/feature/data/model/project_task/project_task_response.dart';
78
import 'package:dipantau_desktop_client/feature/domain/repository/project/project_repository.dart';
89

910
class ProjectRepositoryImpl implements ProjectRepository {
@@ -51,4 +52,34 @@ class ProjectRepositoryImpl implements ProjectRepository {
5152
return Left(ConnectionFailure());
5253
}
5354
}
55+
56+
@override
57+
Future<({Failure? failure, ProjectTaskResponse? response})> getProjectTaskByUserId(String userId) async {
58+
Failure? failure;
59+
ProjectTaskResponse? response;
60+
final isConnected = await networkInfo.isConnected;
61+
if (isConnected) {
62+
try {
63+
response = await remoteDataSource.getProjectTaskByUserId(userId);
64+
} on DioException catch (error) {
65+
final message = error.message ?? error.toString();
66+
if (error.response == null) {
67+
failure = ServerFailure(message);
68+
} else {
69+
final errorMessage = getErrorMessageFromEndpoint(
70+
error.response?.data,
71+
message,
72+
error.response?.statusCode,
73+
);
74+
failure = ServerFailure(errorMessage);
75+
}
76+
} on TypeError catch (error) {
77+
final errorMessage = error.toString();
78+
failure = ParsingFailure(errorMessage);
79+
}
80+
} else {
81+
failure = ConnectionFailure();
82+
}
83+
return (failure: failure, response: response);
84+
}
5485
}

lib/feature/data/repository/track/track_repository_impl.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_cre
77
import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_create_track_image_body.dart';
88
import 'package:dipantau_desktop_client/feature/data/model/create_track/create_track_body.dart';
99
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';
10+
import 'package:dipantau_desktop_client/feature/data/model/manual_create_track/manual_create_track_body.dart';
1011
import 'package:dipantau_desktop_client/feature/data/model/track_user/track_user_response.dart';
1112
import 'package:dipantau_desktop_client/feature/data/model/track_user_lite/track_user_lite_response.dart';
1213
import 'package:dipantau_desktop_client/feature/domain/repository/track/track_repository.dart';
@@ -206,4 +207,34 @@ class TrackRepositoryImpl implements TrackRepository {
206207
}
207208
return (failure: failure, response: response);
208209
}
210+
211+
@override
212+
Future<({Failure? failure, GeneralResponse? response})> createManualTrack(ManualCreateTrackBody body) async {
213+
Failure? failure;
214+
GeneralResponse? response;
215+
final isConnected = await networkInfo.isConnected;
216+
if (isConnected) {
217+
try {
218+
response = await remoteDataSource.createManualTrack(body);
219+
} on DioException catch (error) {
220+
final message = error.message ?? error.toString();
221+
if (error.response == null) {
222+
failure = ServerFailure(message);
223+
} else {
224+
final errorMessage = getErrorMessageFromEndpoint(
225+
error.response?.data,
226+
message,
227+
error.response?.statusCode,
228+
);
229+
failure = ServerFailure(errorMessage);
230+
}
231+
} on TypeError catch (error) {
232+
final errorMessage = error.toString();
233+
failure = ParsingFailure(errorMessage);
234+
}
235+
} else {
236+
failure = ConnectionFailure();
237+
}
238+
return (failure: failure, response: response);
239+
}
209240
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import 'package:dartz/dartz.dart';
22
import 'package:dipantau_desktop_client/core/error/failure.dart';
33
import 'package:dipantau_desktop_client/feature/data/model/project/project_response.dart';
4+
import 'package:dipantau_desktop_client/feature/data/model/project_task/project_task_response.dart';
45

56
abstract class ProjectRepository {
67
Future<Either<Failure, ProjectResponse>> getProject(String userId);
8+
9+
Future<({Failure? failure, ProjectTaskResponse? response})> getProjectTaskByUserId(String userId);
710
}

lib/feature/domain/repository/track/track_repository.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_cre
44
import 'package:dipantau_desktop_client/feature/data/model/create_track/bulk_create_track_image_body.dart';
55
import 'package:dipantau_desktop_client/feature/data/model/create_track/create_track_body.dart';
66
import 'package:dipantau_desktop_client/feature/data/model/general/general_response.dart';
7+
import 'package:dipantau_desktop_client/feature/data/model/manual_create_track/manual_create_track_body.dart';
78
import 'package:dipantau_desktop_client/feature/data/model/track_user/track_user_response.dart';
89
import 'package:dipantau_desktop_client/feature/data/model/track_user_lite/track_user_lite_response.dart';
910

@@ -19,4 +20,6 @@ abstract class TrackRepository {
1920
Future<({Failure? failure, TrackUserResponse? response})> getTrackUser(String userId, String date);
2021

2122
Future<({Failure? failure, GeneralResponse? response})> deleteTrackUser(int trackId);
23+
24+
Future<({Failure? failure, GeneralResponse? response})> createManualTrack(ManualCreateTrackBody body);
2225
}

0 commit comments

Comments
 (0)