feat: adjustement on the serveral part on the profile and quiz result

This commit is contained in:
akhdanre 2025-05-29 15:59:13 +07:00
parent b77229c26a
commit ede385041e
11 changed files with 125 additions and 21 deletions

View File

@ -151,5 +151,7 @@
"quiz_description": "Description", "quiz_description": "Description",
"quiz_total_question": "Total Questions", "quiz_total_question": "Total Questions",
"quiz_duration": "Duration" "quiz_duration": "Duration"
} },
"save_changes" : "Save Changes"
} }

View File

@ -134,5 +134,7 @@
"quiz_description": "Deskripsi", "quiz_description": "Deskripsi",
"quiz_total_question": "Total Pertanyaan", "quiz_total_question": "Total Pertanyaan",
"quiz_duration": "Durasi" "quiz_duration": "Durasi"
} },
"save_changes": "Simpan Perubahan"
} }

View File

@ -136,5 +136,6 @@
"quiz_description": "Penerangan", "quiz_description": "Penerangan",
"quiz_total_question": "Jumlah Soalan", "quiz_total_question": "Jumlah Soalan",
"quiz_duration": "Tempoh" "quiz_duration": "Tempoh"
} },
"save_changes": "Simpan Perubahan"
} }

View File

@ -119,4 +119,88 @@ class AppDialog {
}, },
); );
} }
static Future<bool?> showConfirmationDialog(
BuildContext context, {
required String title,
required String message,
String cancelText = "Batal",
String confirmText = "Yakin",
Color confirmColor = AppColors.primaryBlue,
}) async {
return showDialog<bool>(
context: context,
barrierDismissible: true,
builder: (BuildContext context) {
return Dialog(
backgroundColor: AppColors.background,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
title,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: AppColors.darkText,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 16),
Text(
message,
style: const TextStyle(
fontSize: 14,
color: AppColors.softGrayText,
),
textAlign: TextAlign.center,
),
const SizedBox(height: 24),
Row(
children: [
Expanded(
child: ElevatedButton(
onPressed: () => Navigator.pop(context, false),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: AppColors.primaryBlue,
side: const BorderSide(color: AppColors.primaryBlue),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.symmetric(vertical: 14),
),
child: Text(cancelText),
),
),
const SizedBox(width: 12),
Expanded(
child: ElevatedButton(
onPressed: () => Navigator.pop(context, true),
style: ElevatedButton.styleFrom(
backgroundColor: confirmColor,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
padding: const EdgeInsets.symmetric(vertical: 14),
),
child: Text(confirmText),
),
),
],
)
],
),
),
);
},
);
}
} }

View File

@ -1,6 +1,6 @@
class APIEndpoint { class APIEndpoint {
// static const String baseUrl = "http://172.16.106.19:5000"; static const String baseUrl = "http://192.168.1.18:5000";
static const String baseUrl = "http://103.193.178.121:5000"; // static const String baseUrl = "http://103.193.178.121:5000";
static const String api = "$baseUrl/api"; static const String api = "$baseUrl/api";
static const String login = "/login"; static const String login = "/login";

View File

@ -40,6 +40,7 @@ class UserEntity {
'pic_url': picUrl, 'pic_url': picUrl,
'birth_date': birthDate, 'birth_date': birthDate,
'locale': locale, 'locale': locale,
'phone': phone,
"create_at": createdAt, "create_at": createdAt,
}; };
} }

View File

@ -148,7 +148,7 @@ class LoginController extends GetxController {
void goToRegsPage() => Get.toNamed(AppRoutes.registerPage); void goToRegsPage() => Get.toNamed(AppRoutes.registerPage);
UserEntity _convertLoginResponseToUserEntity(LoginResponseModel response) { UserEntity _convertLoginResponseToUserEntity(LoginResponseModel response) {
logC.i("user id : ${response.id}"); logC.i("user data ${response.toJson()}");
return UserEntity( return UserEntity(
id: response.id ?? '', id: response.id ?? '',
name: response.name, name: response.name,

View File

@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:quiz_app/app/routes/app_pages.dart'; import 'package:quiz_app/app/routes/app_pages.dart';
import 'package:quiz_app/component/notification/pop_up_confirmation.dart';
import 'package:quiz_app/core/endpoint/api_endpoint.dart'; import 'package:quiz_app/core/endpoint/api_endpoint.dart';
import 'package:quiz_app/core/utils/logger.dart'; import 'package:quiz_app/core/utils/logger.dart';
import 'package:quiz_app/data/controllers/user_controller.dart'; import 'package:quiz_app/data/controllers/user_controller.dart';
@ -83,7 +84,15 @@ class ProfileController extends GetxController {
} }
} }
void logout() async { void logout(BuildContext context) async {
final confirm = await AppDialog.showConfirmationDialog(
context,
title: "Keluar dari akun?",
message: "Apakah Anda yakin ingin logout dari akun ini?",
confirmText: "Logout",
);
if (confirm == true) {
try { try {
await _googleAuthService.signOut(); await _googleAuthService.signOut();
await _userStorageService.clearUser(); await _userStorageService.clearUser();
@ -95,6 +104,7 @@ class ProfileController extends GetxController {
Get.snackbar("Error", "Gagal logout dari Google"); Get.snackbar("Error", "Gagal logout dari Google");
} }
} }
}
void editProfile() { void editProfile() {
Get.toNamed(AppRoutes.updateProfilePage); Get.toNamed(AppRoutes.updateProfilePage);

View File

@ -36,7 +36,7 @@ class ProfileView extends GetView<ProfileController> {
const SizedBox(height: 10), const SizedBox(height: 10),
_profileDetails(cardRadius: cardRadius), _profileDetails(cardRadius: cardRadius),
const SizedBox(height: 10), const SizedBox(height: 10),
_settingsSection(cardRadius: cardRadius), _settingsSection(context, cardRadius: cardRadius),
const SizedBox(height: 10), const SizedBox(height: 10),
_legalSection(cardRadius: cardRadius), _legalSection(cardRadius: cardRadius),
const SizedBox(height: 20), const SizedBox(height: 20),
@ -161,7 +161,7 @@ class ProfileView extends GetView<ProfileController> {
), ),
); );
Widget _settingsSection({required BorderRadius cardRadius}) => Card( Widget _settingsSection(BuildContext context, {required BorderRadius cardRadius}) => Card(
color: Colors.white, color: Colors.white,
elevation: 1, elevation: 1,
shadowColor: AppColors.shadowPrimary, shadowColor: AppColors.shadowPrimary,
@ -177,7 +177,7 @@ class ProfileView extends GetView<ProfileController> {
const Divider(height: 1), const Divider(height: 1),
_settingsTile(Get.context!, icon: LucideIcons.languages, title: tr('change_language'), onTap: () => _showLanguageDialog(Get.context!)), _settingsTile(Get.context!, icon: LucideIcons.languages, title: tr('change_language'), onTap: () => _showLanguageDialog(Get.context!)),
_settingsTile(Get.context!, _settingsTile(Get.context!,
icon: LucideIcons.logOut, title: tr('logout'), iconColor: Colors.red, textColor: Colors.red, onTap: controller.logout), icon: LucideIcons.logOut, title: tr('logout'), iconColor: Colors.red, textColor: Colors.red, onTap: () => controller.logout(context)),
], ],
), ),
), ),

View File

@ -1,5 +1,7 @@
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:quiz_app/app/const/colors/app_colors.dart';
import 'package:quiz_app/component/global_button.dart'; import 'package:quiz_app/component/global_button.dart';
import 'package:quiz_app/component/global_dropdown_field.dart'; import 'package:quiz_app/component/global_dropdown_field.dart';
import 'package:quiz_app/component/global_text_field.dart'; import 'package:quiz_app/component/global_text_field.dart';
@ -10,7 +12,9 @@ class UpdateProfilePage extends GetView<UpdateProfileController> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
backgroundColor: AppColors.background2,
appBar: AppBar( appBar: AppBar(
backgroundColor: AppColors.background2,
title: Text('Update Profile'), title: Text('Update Profile'),
centerTitle: true, centerTitle: true,
), ),
@ -56,7 +60,7 @@ class UpdateProfilePage extends GetView<UpdateProfileController> {
)), )),
SizedBox(height: 32), SizedBox(height: 32),
Center( Center(
child: GlobalButton(text: "save_changes", onPressed: controller.saveProfile), child: GlobalButton(text: tr("save_changes"), onPressed: controller.saveProfile),
), ),
], ],
), ),

View File

@ -95,7 +95,7 @@ class QuizResultView extends GetView<QuizResultController> {
final parsed = _parseAnswer(question, answer.selectedAnswer); final parsed = _parseAnswer(question, answer.selectedAnswer);
return QuizItemWAComponent( return QuizItemWAComponent(
index: question.index, index: index + 1,
isCorrect: answer.isCorrect, isCorrect: answer.isCorrect,
question: question.question, question: question.question,
targetAnswer: parsed.targetAnswer, targetAnswer: parsed.targetAnswer,