Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
include: package:flutter_lints/flutter.yaml

analyzer:
errors:
prefer_final_locals: ignore
exclude:
- lib/generated/**
- lib/l10n/**
Expand Down
5 changes: 5 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<application
android:label="elevate_tracking_app"
android:name="${applicationName}"
Expand Down
4 changes: 4 additions & 0 deletions ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library to upload images</string>
<key>NSCameraUsageDescription</key>
<string>We need access to your camera to take pictures</string>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
Expand Down
28 changes: 27 additions & 1 deletion lib/api/client/api_client.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import 'package:dio/dio.dart';
import 'package:elevate_tracking_app/api/models/requests/auth/update_profile_info_request_dto.dart';
import 'package:elevate_tracking_app/api/models/requests/login_request.dart';
import 'package:elevate_tracking_app/api/models/responses/login_response.dart';
import 'package:elevate_tracking_app/api/models/responses/profile_info_response_dto/profile_info_response_dto.dart';
import 'package:elevate_tracking_app/api/models/responses/upload_profile_image_response_dto/upload_profile_image_response_dto.dart';
import 'package:elevate_tracking_app/api/models/responses/vehicle_response_dto/vehicle_response_dto.dart';
import 'package:elevate_tracking_app/core/constants/const_keys.dart';
import 'package:elevate_tracking_app/api/models/responses/logout_response_dto.dart';
import 'package:injectable/injectable.dart';
import 'package:retrofit/retrofit.dart';

import '../../core/constants/end_points.dart';

part 'api_client.g.dart';
Expand All @@ -16,4 +21,25 @@ abstract class ApiClient {

@POST(EndPoints.login)
Future<LoginResponse> login(@Body() LoginRequest loginRequest);

@GET(EndPoints.profile)
Future<ProfileInfoResponseDto> getLoggedDriverData();

@PUT(EndPoints.editProfile)
Future<ProfileInfoResponseDto> editProfile(
@Body() UpdateProfileInfoRequestDto updateProfileInfoRequestDto,
);

@PUT(EndPoints.uploadProfilePhoto)
@MultiPart()
Future<UploadProfileImageResponseDto> uploadProfilePhoto(
@Part(name: ConstKeys.photo) MultipartFile photo,
);

@GET('${EndPoints.vehicle}/{id}')
Future<VehicleResponseDto> getVehicle(@Path("id") String id);

@GET(EndPoints.logout)
Future<LogoutResponseDto> logout();

}
7 changes: 6 additions & 1 deletion lib/api/data_source/auth_local_data_source_impl.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class AuthLocalDataSourceImpl implements AuthLocalDataSource {
key: ConstKeys.kUserPassword,
value: loginRequestEntity.password,
);
}else{
} else {
await _secureStorage.delete(key: ConstKeys.kUserLogin);
await _secureStorage.delete(key: ConstKeys.kUserPassword);
}
Expand All @@ -36,4 +36,9 @@ class AuthLocalDataSourceImpl implements AuthLocalDataSource {
Future<void> saveUserToken({required String token}) async {
await _secureStorage.write(key: ConstKeys.keyUserToken, value: token);
}

@override
Future<void> userLogout() async {
await _secureStorage.delete(key: ConstKeys.keyUserToken);
}
}
57 changes: 57 additions & 0 deletions lib/api/data_source/auth_remote_data_source_impl.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:elevate_tracking_app/api/client/api_client.dart';
import 'package:elevate_tracking_app/api/mapper/login_mapper.dart';
import 'package:elevate_tracking_app/api/mapper/profile_info_mapper.dart';
import 'package:elevate_tracking_app/api/models/responses/logout_response_dto.dart';
import 'package:elevate_tracking_app/core/api_result/api_result.dart';
import 'package:elevate_tracking_app/core/api_result/safe_api_call.dart';
import 'package:elevate_tracking_app/data/data_source/auth_remote_data_source.dart';
import 'package:elevate_tracking_app/domain/entites/driver_entity.dart';
import 'package:elevate_tracking_app/domain/entites/login_entity.dart';
import 'package:elevate_tracking_app/domain/entites/logout_response_entity.dart';
import 'package:elevate_tracking_app/domain/entites/requests/login_request_entity.dart';
import 'package:elevate_tracking_app/domain/entites/requests/update_profile_info_request_entity.dart';
import 'package:elevate_tracking_app/domain/entites/upload_profile_image_response_entity.dart';
import 'package:elevate_tracking_app/domain/entites/vehicle_entity.dart';
import 'package:injectable/injectable.dart';

@Injectable(as: AuthRemoteDataSource)
Expand All @@ -20,4 +29,52 @@ class AuthRemoteDataSourceImpl implements AuthRemoteDataSource {
(response) => response.toEntity(),
);
}

@override
Future<ApiResult<DriverEntity>> getLoggedDriverData() {
return safeApiCall(
() => _apiClient.getLoggedDriverData(),
(response) => response.driver!.toEntity(),
);
}

@override
Future<ApiResult<DriverEntity>> editProfile(
UpdateProfileInfoRequestEntity updateProfileInfoRequestEntity,
) {
return safeApiCall(
() => _apiClient.editProfile(updateProfileInfoRequestEntity.toDto()),
(response) => response.driver!.toEntity(),
);
}

@override
Future<ApiResult<UploadProfileImageResponseEntity>> uploadProfilePhoto(
File file,
) async {
final multipartFile = await MultipartFile.fromFile(
file.path,
filename: file.uri.pathSegments.last,
);
return safeApiCall(
() => _apiClient.uploadProfilePhoto(multipartFile),
(response) => response.toEntity(),
);
}

@override
Future<ApiResult<VehicleEntity>> getVehicle(String id) {
return safeApiCall(
() => _apiClient.getVehicle(id),
(response) => response.vehicle!.toEntity(),
);
}

@override
Future<ApiResult<LogoutResponseEntity>> logout() async {
return safeApiCall<LogoutResponseDto, LogoutResponseEntity>(
() => _apiClient.logout(),
(dto) => dto.toEntity(),
);
}
}
68 changes: 68 additions & 0 deletions lib/api/mapper/profile_info_mapper.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import 'package:elevate_tracking_app/api/models/responses/driver_dto.dart';
import 'package:elevate_tracking_app/api/models/requests/auth/update_profile_info_request_dto.dart';
import 'package:elevate_tracking_app/api/models/responses/upload_profile_image_response_dto/upload_profile_image_response_dto.dart';
import 'package:elevate_tracking_app/api/models/responses/vehicle_dto.dart';
import 'package:elevate_tracking_app/domain/entites/driver_entity.dart';
import 'package:elevate_tracking_app/domain/entites/requests/update_profile_info_request_entity.dart';
import 'package:elevate_tracking_app/domain/entites/upload_profile_image_response_entity.dart';
import 'package:elevate_tracking_app/domain/entites/vehicle_entity.dart';
import 'package:elevate_tracking_app/api/models/responses/logout_response_dto.dart';
import 'package:elevate_tracking_app/domain/entites/logout_response_entity.dart';

extension DriverMapper on DriverDto {
DriverEntity toEntity() {
return DriverEntity(
id: id,
country: country,
firstName: firstName,
lastName: lastName,
vehicleType: vehicleType,
vehicleNumber: vehicleNumber,
vehicleLicense: vehicleLicense,
nid: nid,
nidImg: nidImg,
email: email,
gender: gender,
phone: phone,
photo: photo,
role: role,
createdAt: createdAt,
);
}
}

extension UpdateProfileInfoRequestMapper on UpdateProfileInfoRequestEntity {
UpdateProfileInfoRequestDto toDto() {
return UpdateProfileInfoRequestDto(
firstName: firstName,
lastName: lastName,
email: email,
phone: phone,
);
}
}

extension UploadProfileImageResponseMapper on UploadProfileImageResponseDto {
UploadProfileImageResponseEntity toEntity() {
return UploadProfileImageResponseEntity(message: message);
}
}

extension VehicleMapper on VehicleDto {
VehicleEntity toEntity() {
return VehicleEntity(
id: id,
type: type,
image: image,
createdAt: createdAt,
updatedAt: updatedAt,
v: v,
);
}
}

extension LogoutResponseMapper on LogoutResponseDto {
LogoutResponseEntity toEntity() {
return LogoutResponseEntity(message: message);
}
}
26 changes: 26 additions & 0 deletions lib/api/models/requests/auth/update_profile_info_request_dto.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'update_profile_info_request_dto.g.dart';

@JsonSerializable()
class UpdateProfileInfoRequestDto extends Equatable {
final String? firstName;
final String? lastName;
final String? email;
final String? phone;

const UpdateProfileInfoRequestDto({
required this.firstName,
required this.lastName,
required this.email,
required this.phone,
});

factory UpdateProfileInfoRequestDto.fromJson(Map<String, dynamic> json) =>
_$UpdateProfileInfoRequestDtoFromJson(json);

Map<String, dynamic> toJson() => _$UpdateProfileInfoRequestDtoToJson(this);

@override
List<Object?> get props => [firstName, lastName, email, phone];
}
71 changes: 71 additions & 0 deletions lib/api/models/responses/driver_dto.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';

part 'driver_dto.g.dart';

@JsonSerializable()
class DriverDto extends Equatable {
@JsonKey(name: '_id')
final String? id;
final String? country;
final String? firstName;
final String? lastName;
final String? vehicleType;
final String? vehicleNumber;
final String? vehicleLicense;
@JsonKey(name: 'NID')
final String? nid;
@JsonKey(name: 'NIDImg')
final String? nidImg;
final String? email;
final String? gender;
final String? phone;
final String? photo;
final String? role;
final DateTime? createdAt;

const DriverDto({
this.id,
this.country,
this.firstName,
this.lastName,
this.vehicleType,
this.vehicleNumber,
this.vehicleLicense,
this.nid,
this.nidImg,
this.email,
this.gender,
this.phone,
this.photo,
this.role,
this.createdAt,
});

factory DriverDto.fromJson(Map<String, dynamic> json) {
return _$DriverDtoFromJson(json);
}

Map<String, dynamic> toJson() => _$DriverDtoToJson(this);

@override
List<Object?> get props {
return [
id,
country,
firstName,
lastName,
vehicleType,
vehicleNumber,
vehicleLicense,
nid,
nidImg,
email,
gender,
phone,
photo,
role,
createdAt,
];
}
}
19 changes: 19 additions & 0 deletions lib/api/models/responses/logout_response_dto.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';

part 'logout_response_dto.g.dart';

@JsonSerializable()
class LogoutResponseDto extends Equatable {
final String? message;

const LogoutResponseDto({this.message});

factory LogoutResponseDto.fromJson(Map<String, dynamic> json) =>
_$LogoutResponseDtoFromJson(json);

Map<String, dynamic> toJson() => _$LogoutResponseDtoToJson(this);

@override
List<Object?> get props => [message];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import 'package:elevate_tracking_app/api/models/responses/driver_dto.dart';
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';



part 'profile_info_response_dto.g.dart';

@JsonSerializable()
class ProfileInfoResponseDto extends Equatable {
final String? message;
final DriverDto? driver;

const ProfileInfoResponseDto({this.message, this.driver});

factory ProfileInfoResponseDto.fromJson(Map<String, dynamic> json) {
return _$ProfileInfoResponseDtoFromJson(json);
}

Map<String, dynamic> toJson() => _$ProfileInfoResponseDtoToJson(this);

@override
List<Object?> get props => [message, driver];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';

part 'upload_profile_image_response_dto.g.dart';

@JsonSerializable()
class UploadProfileImageResponseDto extends Equatable {
final String? message;

const UploadProfileImageResponseDto({this.message});

factory UploadProfileImageResponseDto.fromJson(Map<String, dynamic> json) {
return _$UploadProfileImageResponseDtoFromJson(json);
}

Map<String, dynamic> toJson() => _$UploadProfileImageResponseDtoToJson(this);

@override
List<Object?> get props => [message];
}
Loading
Loading