feat: done working on the profile update
This commit is contained in:
parent
175f4e6668
commit
1c6ce0d023
|
@ -22,4 +22,7 @@ class APIEndpoint {
|
||||||
static const String subject = "/subject";
|
static const String subject = "/subject";
|
||||||
|
|
||||||
static const String session = "/session";
|
static const String session = "/session";
|
||||||
|
|
||||||
|
static const String userData = "/user";
|
||||||
|
static const String userUpdate = "/user/update";
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,23 +3,29 @@ class UserEntity {
|
||||||
final String name;
|
final String name;
|
||||||
final String email;
|
final String email;
|
||||||
final String? picUrl;
|
final String? picUrl;
|
||||||
|
final String? birthDate;
|
||||||
final String? locale;
|
final String? locale;
|
||||||
|
final String? phone;
|
||||||
|
|
||||||
UserEntity({
|
UserEntity({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.email,
|
required this.email,
|
||||||
this.picUrl,
|
this.picUrl,
|
||||||
|
this.birthDate,
|
||||||
this.locale,
|
this.locale,
|
||||||
|
this.phone,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory UserEntity.fromJson(Map<String, dynamic> json) {
|
factory UserEntity.fromJson(Map<String, dynamic> json) {
|
||||||
return UserEntity(
|
return UserEntity(
|
||||||
id: json['id'],
|
id: json['id'] ?? '',
|
||||||
name: json['name'],
|
name: json['name'] ?? '',
|
||||||
email: json['email'],
|
email: json['email'] ?? '',
|
||||||
picUrl: json['pic_url'],
|
picUrl: json['pic_url'],
|
||||||
|
birthDate: json['birth_date'],
|
||||||
locale: json['locale'],
|
locale: json['locale'],
|
||||||
|
phone: json['phone'],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +35,7 @@ UserEntity({
|
||||||
'name': name,
|
'name': name,
|
||||||
'email': email,
|
'email': email,
|
||||||
'pic_url': picUrl,
|
'pic_url': picUrl,
|
||||||
|
'birth_date': birthDate,
|
||||||
'locale': locale,
|
'locale': locale,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
class UserFullModel {
|
||||||
|
final String id;
|
||||||
|
final String googleId;
|
||||||
|
final String email;
|
||||||
|
final String name;
|
||||||
|
final String birthDate;
|
||||||
|
final String picUrl;
|
||||||
|
final String phone;
|
||||||
|
final String locale;
|
||||||
|
final String createdAt;
|
||||||
|
final String updatedAt;
|
||||||
|
|
||||||
|
UserFullModel({
|
||||||
|
required this.id,
|
||||||
|
required this.googleId,
|
||||||
|
required this.email,
|
||||||
|
required this.name,
|
||||||
|
required this.birthDate,
|
||||||
|
required this.picUrl,
|
||||||
|
required this.phone,
|
||||||
|
required this.locale,
|
||||||
|
required this.createdAt,
|
||||||
|
required this.updatedAt,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory UserFullModel.fromJson(Map<String, dynamic> json) {
|
||||||
|
return UserFullModel(
|
||||||
|
id: json['id'] ?? '',
|
||||||
|
googleId: json['google_id'] ?? '',
|
||||||
|
email: json['email'] ?? '',
|
||||||
|
name: json['name'] ?? '',
|
||||||
|
birthDate: json['birth_date'] ?? '',
|
||||||
|
picUrl: json['pic_url'] ?? '',
|
||||||
|
phone: json['phone'] ?? '',
|
||||||
|
locale: json['locale'] ?? '',
|
||||||
|
createdAt: json['created_at'] ?? '',
|
||||||
|
updatedAt: json['updated_at'] ?? '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {
|
||||||
|
'id': id,
|
||||||
|
'google_id': googleId,
|
||||||
|
'email': email,
|
||||||
|
'name': name,
|
||||||
|
'birth_date': birthDate,
|
||||||
|
'pic_url': picUrl,
|
||||||
|
'phone': phone,
|
||||||
|
'locale': locale,
|
||||||
|
'created_at': createdAt,
|
||||||
|
'updated_at': updatedAt,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:quiz_app/core/endpoint/api_endpoint.dart';
|
||||||
|
import 'package:quiz_app/core/utils/logger.dart';
|
||||||
|
import 'package:quiz_app/data/models/base/base_model.dart';
|
||||||
|
import 'package:quiz_app/data/models/user/user_full_model.dart';
|
||||||
|
import 'package:quiz_app/data/providers/dio_client.dart';
|
||||||
|
|
||||||
|
class UserService extends GetxService {
|
||||||
|
late final Dio _dio;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
_dio = Get.find<ApiClient>().dio;
|
||||||
|
super.onInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<bool> updateProfileData(String id, String name, {String? birthDate, String? locale, String? phone}) async {
|
||||||
|
try {
|
||||||
|
final response = await _dio.post(APIEndpoint.userUpdate, data: {
|
||||||
|
"id": id,
|
||||||
|
"name": name,
|
||||||
|
"birth_date": birthDate,
|
||||||
|
"locale": locale,
|
||||||
|
"phone": phone,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logC.e("update profile error: $e");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<BaseResponseModel<UserFullModel>?> getUserData(String id) async {
|
||||||
|
try {
|
||||||
|
final response = await _dio.get("${APIEndpoint.userData}/$id");
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
final parsedResponse = BaseResponseModel<UserFullModel>.fromJson(
|
||||||
|
response.data,
|
||||||
|
(data) => UserFullModel.fromJson(data),
|
||||||
|
);
|
||||||
|
return parsedResponse;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logC.e("get user data error: $e");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,17 @@
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:quiz_app/data/controllers/user_controller.dart';
|
||||||
|
import 'package:quiz_app/data/services/user_service.dart';
|
||||||
|
import 'package:quiz_app/data/services/user_storage_service.dart';
|
||||||
import 'package:quiz_app/feature/profile/controller/update_profile_controller.dart';
|
import 'package:quiz_app/feature/profile/controller/update_profile_controller.dart';
|
||||||
|
|
||||||
class UpdateProfileBinding extends Bindings {
|
class UpdateProfileBinding extends Bindings {
|
||||||
@override
|
@override
|
||||||
void dependencies() {
|
void dependencies() {
|
||||||
Get.lazyPut(() => UpdateProfileController());
|
Get.lazyPut(() => UserService());
|
||||||
|
Get.lazyPut(() => UpdateProfileController(
|
||||||
|
Get.find<UserService>(),
|
||||||
|
Get.find<UserController>(),
|
||||||
|
Get.find<UserStorageService>(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,108 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
import 'package:quiz_app/core/utils/custom_floating_loading.dart';
|
||||||
|
import 'package:quiz_app/core/utils/custom_notification.dart';
|
||||||
|
import 'package:quiz_app/data/controllers/user_controller.dart';
|
||||||
|
import 'package:quiz_app/data/entity/user/user_entity.dart';
|
||||||
|
import 'package:quiz_app/data/services/user_service.dart';
|
||||||
|
import 'package:quiz_app/data/services/user_storage_service.dart';
|
||||||
|
|
||||||
class UpdateProfileController extends GetxController {
|
class UpdateProfileController extends GetxController {
|
||||||
|
final UserController _userController;
|
||||||
|
final UserStorageService _userStorageService;
|
||||||
|
final UserService _userService;
|
||||||
|
|
||||||
|
UpdateProfileController(
|
||||||
|
this._userService,
|
||||||
|
this._userController,
|
||||||
|
this._userStorageService,
|
||||||
|
);
|
||||||
|
|
||||||
final nameController = TextEditingController();
|
final nameController = TextEditingController();
|
||||||
final phoneController = TextEditingController();
|
final phoneController = TextEditingController();
|
||||||
final birthDateController = TextEditingController();
|
final birthDateController = TextEditingController();
|
||||||
|
|
||||||
var selectedLocale = 'en-US'.obs;
|
var selectedLocale = 'en-US'.obs;
|
||||||
|
|
||||||
final Map<String, String> localeMap = {
|
final Map<String, String> localeMap = {
|
||||||
'English': 'en-US',
|
'English': 'en-US',
|
||||||
'Indonesian': 'id-ID',
|
'Indonesian': 'id-ID',
|
||||||
'French': 'fr-FR',
|
'French': 'fr-FR',
|
||||||
'Spanish': 'es-ES',
|
'Spanish': 'es-ES',
|
||||||
};
|
};
|
||||||
void saveProfile() {
|
|
||||||
Get.snackbar('Success', 'Profile updated successfully');
|
@override
|
||||||
|
void onInit() {
|
||||||
|
final userData = _userController.userData!;
|
||||||
|
nameController.text = userData.name;
|
||||||
|
phoneController.text = userData.phone ?? '';
|
||||||
|
birthDateController.text = userData.birthDate ?? '';
|
||||||
|
super.onInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _validateInputs() {
|
||||||
|
final name = nameController.text.trim();
|
||||||
|
final phone = phoneController.text.trim();
|
||||||
|
final birthDate = birthDateController.text.trim();
|
||||||
|
print(birthDate);
|
||||||
|
|
||||||
|
if (name.isEmpty || phone.isEmpty || birthDate.isEmpty) {
|
||||||
|
Get.snackbar('Validation Error', 'All fields must be filled.', snackPosition: SnackPosition.TOP);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_isValidDateFormat(birthDate)) {
|
||||||
|
Get.snackbar('Validation Error', 'birth date must valid.', snackPosition: SnackPosition.TOP);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> saveProfile() async {
|
||||||
|
if (!_validateInputs()) return;
|
||||||
|
|
||||||
|
CustomFloatingLoading.showLoadingDialog(Get.context!);
|
||||||
|
|
||||||
|
final isSuccessUpdate = await _userService.updateProfileData(
|
||||||
|
_userController.userData!.id,
|
||||||
|
nameController.text.trim(),
|
||||||
|
birthDate: birthDateController.text.trim(),
|
||||||
|
phone: phoneController.text.trim(),
|
||||||
|
locale: selectedLocale.value,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isSuccessUpdate) {
|
||||||
|
final response = await _userService.getUserData(_userController.userData!.id);
|
||||||
|
|
||||||
|
if (response?.data != null) {
|
||||||
|
final userNew = response!.data!;
|
||||||
|
final newUser = UserEntity(
|
||||||
|
id: userNew.id,
|
||||||
|
email: userNew.email,
|
||||||
|
name: userNew.name,
|
||||||
|
birthDate: userNew.birthDate,
|
||||||
|
locale: userNew.locale,
|
||||||
|
picUrl: userNew.picUrl,
|
||||||
|
phone: userNew.phone,
|
||||||
|
);
|
||||||
|
|
||||||
|
_userStorageService.saveUser(newUser);
|
||||||
|
_userController.userData = newUser;
|
||||||
|
|
||||||
|
_userController.email.value = userNew.email;
|
||||||
|
_userController.userName.value = userNew.name;
|
||||||
|
_userController.userImage.value = userNew.picUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Get.back();
|
||||||
|
|
||||||
|
CustomNotification.success(title: "Success", message: "Profile updated successfully");
|
||||||
|
CustomFloatingLoading.hideLoadingDialog(Get.context!);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _isValidDateFormat(String date) {
|
||||||
|
final regex = RegExp(r'^([0-2][0-9]|(3)[0-1])\-((0[1-9])|(1[0-2]))\-\d{4}$');
|
||||||
|
return regex.hasMatch(date);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue