Feat: add logic create in queue potter
This commit is contained in:
parent
f395d6c4d2
commit
d34b170aab
|
@ -0,0 +1,74 @@
|
|||
import 'dart:developer';
|
||||
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:e_porter/domain/repositories/porter_queue_repository.dart';
|
||||
|
||||
import '../../domain/models/porter_queue_model.dart';
|
||||
|
||||
class PorterQueueRepositoryImpl implements PorterQueueRepository {
|
||||
final FirebaseFirestore _firestore;
|
||||
|
||||
PorterQueueRepositoryImpl({
|
||||
FirebaseFirestore? firestore,
|
||||
}) : _firestore = firestore ?? FirebaseFirestore.instance;
|
||||
|
||||
@override
|
||||
Future<String> createPorterQueue(String userId) async {
|
||||
try {
|
||||
log('[PorterRepository] Membuat antrian porter untuk userId: $userId');
|
||||
|
||||
// Periksa apakah porter dengan userId ini sudah ada
|
||||
final existingPorter = await getPorterByUserId(userId);
|
||||
if (existingPorter != null) {
|
||||
log('[PorterRepository] Porter dengan userId: $userId sudah ada di antrian');
|
||||
return existingPorter.id!;
|
||||
}
|
||||
|
||||
// Buat data porter baru
|
||||
final now = DateTime.now();
|
||||
final porterData = PorterQueueModel(
|
||||
userId: userId,
|
||||
isTaken: true,
|
||||
onlineAt: now,
|
||||
).toJson();
|
||||
|
||||
// Simpan ke Firestore
|
||||
final docRef = await _firestore.collection('porterOnline').add(porterData);
|
||||
|
||||
log('[PorterRepository] Berhasil membuat antrian porter dengan ID: ${docRef.id}');
|
||||
return docRef.id;
|
||||
} catch (e) {
|
||||
log('[PorterRepository] Error membuat antrian porter: $e');
|
||||
throw Exception('Gagal membuat antrian porter: $e');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<PorterQueueModel?> getPorterByUserId(String userId) async {
|
||||
try {
|
||||
final snapshot = await _firestore.collection('porterOnline').where('userId', isEqualTo: userId).limit(1).get();
|
||||
|
||||
if (snapshot.docs.isNotEmpty) {
|
||||
return PorterQueueModel.fromJson(snapshot.docs.first.data(), docId: snapshot.docs.first.id);
|
||||
}
|
||||
return null;
|
||||
} catch (e) {
|
||||
log('[PorterRepository] Error mendapatkan porter by userId: $e');
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> deletePorterQueue(String porterId) async {
|
||||
try {
|
||||
log('[PorterRepository] Menghapus antrian porter dengan ID: $porterId');
|
||||
|
||||
await _firestore.collection('porterOnline').doc(porterId).delete();
|
||||
|
||||
log('[PorterRepository] Berhasil menghapus antrian porter dengan ID: $porterId');
|
||||
} catch (e) {
|
||||
log('[PorterRepository] Error menghapus antrian porter: $e');
|
||||
throw Exception('Gagal menghapus antrian porter: $e');
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
import 'package:e_porter/domain/usecases/porter_queue_usecase.dart';
|
||||
import 'package:e_porter/presentation/controllers/porter_queue_controller.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
import '../../data/repositories/porter_queue_repository_impl.dart';
|
||||
import '../repositories/porter_queue_repository.dart';
|
||||
|
||||
class PorterQueueBinding extends Bindings {
|
||||
@override
|
||||
void dependencies() {
|
||||
// Repository
|
||||
Get.lazyPut<PorterQueueRepository>(
|
||||
() => PorterQueueRepositoryImpl(),
|
||||
);
|
||||
|
||||
// UseCase
|
||||
Get.lazyPut<PorterQueueUsecase>(
|
||||
() => PorterQueueUsecase(Get.find<PorterQueueRepository>()),
|
||||
);
|
||||
|
||||
// Controller
|
||||
Get.lazyPut<PorterQueueController>(
|
||||
() => PorterQueueController(Get.find<PorterQueueUsecase>()),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
|
||||
class PorterQueueModel {
|
||||
final String? id;
|
||||
final String userId;
|
||||
final bool isTaken;
|
||||
final DateTime onlineAt;
|
||||
|
||||
PorterQueueModel({
|
||||
this.id,
|
||||
required this.userId,
|
||||
required this.isTaken,
|
||||
required this.onlineAt,
|
||||
});
|
||||
|
||||
factory PorterQueueModel.fromJson(Map<String, dynamic> json, {String? docId}) {
|
||||
return PorterQueueModel(
|
||||
id: docId ?? json['id'],
|
||||
userId: json['userId'] ?? '',
|
||||
isTaken: json['isTaken'] ?? false,
|
||||
onlineAt: (json['onlineAt'] is Timestamp)
|
||||
? (json['onlineAt'] as Timestamp).toDate()
|
||||
: DateTime.fromMillisecondsSinceEpoch(json['onlineAt'] ?? 0),
|
||||
);
|
||||
}
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
return {
|
||||
'userId': userId,
|
||||
'isTaken': isTaken,
|
||||
'onlineAt': onlineAt,
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import '../models/porter_queue_model.dart';
|
||||
|
||||
abstract class PorterQueueRepository {
|
||||
Future<String> createPorterQueue(String userId);
|
||||
Future<PorterQueueModel?> getPorterByUserId(String userId);
|
||||
Future<void> deletePorterQueue(String porterId);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
import '../models/porter_queue_model.dart';
|
||||
import '../repositories/porter_queue_repository.dart';
|
||||
|
||||
class PorterQueueUsecase {
|
||||
final PorterQueueRepository _repository;
|
||||
|
||||
PorterQueueUsecase(this._repository);
|
||||
|
||||
Future<String> createPorterQueue(String userId) {
|
||||
return _repository.createPorterQueue(userId);
|
||||
}
|
||||
|
||||
Future<PorterQueueModel?> getPorterByUserId(String userId) {
|
||||
return _repository.getPorterByUserId(userId);
|
||||
}
|
||||
|
||||
Future<void> deletePorterQueue(String porterId) {
|
||||
return _repository.deletePorterQueue(porterId);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
import 'package:e_porter/domain/models/porter_queue_model.dart';
|
||||
import 'package:e_porter/domain/usecases/porter_queue_usecase.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
class PorterQueueController {
|
||||
final PorterQueueUsecase _porterQueueUsecase;
|
||||
|
||||
PorterQueueController(this._porterQueueUsecase);
|
||||
|
||||
final RxBool isLoading = false.obs;
|
||||
final RxString error = ''.obs;
|
||||
final Rx<PorterQueueModel?> currentPorter = Rx<PorterQueueModel?>(null);
|
||||
|
||||
Future<String> createPorterQueue(String userId) async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
error.value = '';
|
||||
|
||||
final porterId = await _porterQueueUsecase.createPorterQueue(userId);
|
||||
|
||||
final porter = await _porterQueueUsecase.getPorterByUserId(userId);
|
||||
currentPorter.value = porter;
|
||||
|
||||
return porterId;
|
||||
} catch (e) {
|
||||
error.value = 'Gagal membuat antrian porter: $e';
|
||||
throw Exception(error.value);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool validatePorterQueueForDeletion() {
|
||||
final porter = currentPorter.value;
|
||||
return porter != null && porter.id != null;
|
||||
}
|
||||
|
||||
Future<bool> deletePorterQueue(String porterId) async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
error.value = '';
|
||||
|
||||
await _porterQueueUsecase.deletePorterQueue(porterId);
|
||||
currentPorter.value = null;
|
||||
|
||||
return true;
|
||||
} catch (e) {
|
||||
error.value = 'Gagal menghapus antrian porter: $e';
|
||||
return false;
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
Future<String?> validateAndGetUserId(String? userId) async {
|
||||
if (userId == null || userId.isEmpty) {
|
||||
error.value = 'User ID tidak ditemukan. Silakan login kembali.';
|
||||
return null;
|
||||
}
|
||||
return userId;
|
||||
}
|
||||
|
||||
Future<void> loadCurrentPorter(String userId) async {
|
||||
try {
|
||||
isLoading.value = true;
|
||||
error.value = '';
|
||||
|
||||
final porter = await _porterQueueUsecase.getPorterByUserId(userId);
|
||||
currentPorter.value = porter;
|
||||
} catch (e) {
|
||||
error.value = 'Gagal memuat data porter: $e';
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ import 'package:e_porter/_core/component/icons/icons_library.dart';
|
|||
import 'package:e_porter/_core/constants/colors.dart';
|
||||
import 'package:e_porter/_core/constants/typography.dart';
|
||||
import 'package:e_porter/_core/service/preferences_service.dart';
|
||||
import 'package:e_porter/presentation/controllers/porter_queue_controller.dart';
|
||||
import 'package:e_porter/presentation/screens/home/component/card_service_porter.dart';
|
||||
import 'package:e_porter/presentation/screens/home/component/profile_avatar.dart';
|
||||
import 'package:e_porter/presentation/screens/home/component/summary_card.dart';
|
||||
|
@ -18,6 +19,7 @@ import 'package:flutter_svg/flutter_svg.dart';
|
|||
import 'package:get/get.dart';
|
||||
import 'package:zoom_tap_animation/zoom_tap_animation.dart';
|
||||
|
||||
import '../../../../_core/utils/snackbar/snackbar_helper.dart';
|
||||
import '../../../../domain/models/user_entity.dart';
|
||||
|
||||
class HomeScreen extends StatefulWidget {
|
||||
|
@ -31,6 +33,7 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
int _current = 0;
|
||||
late final String role;
|
||||
late Future<UserData?> _userDataFuture;
|
||||
late PorterQueueController _porterQueueController;
|
||||
final CarouselSliderController _carouselController = CarouselSliderController();
|
||||
|
||||
final List<Widget> imageList = [
|
||||
|
@ -51,6 +54,106 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
super.initState();
|
||||
role = Get.arguments ?? 'penumpang';
|
||||
_userDataFuture = PreferencesService.getUserData();
|
||||
|
||||
if (role == 'porter') {
|
||||
_porterQueueController = Get.find<PorterQueueController>();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handlePorterQueueCreation() async {
|
||||
try {
|
||||
final userData = await PreferencesService.getUserData();
|
||||
if (userData?.uid == null) {
|
||||
SnackbarHelper.showError(
|
||||
'Gagal',
|
||||
'User ID tidak ditemukan. Silakan login kembali.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (Get.isSnackbarOpen) {
|
||||
Get.closeAllSnackbars();
|
||||
}
|
||||
|
||||
_showLoadingDialog();
|
||||
|
||||
await _porterQueueController.createPorterQueue(userData!.uid);
|
||||
|
||||
if (Get.isDialogOpen == true) {
|
||||
Get.back();
|
||||
}
|
||||
|
||||
SnackbarHelper.showSuccess(
|
||||
'Berhasil',
|
||||
'Anda telah masuk dalam antrian porter',
|
||||
);
|
||||
|
||||
setState(() {});
|
||||
} catch (e) {
|
||||
if (Get.isDialogOpen == true) {
|
||||
Get.back();
|
||||
}
|
||||
|
||||
SnackbarHelper.showError(
|
||||
'Gagal',
|
||||
'Gagal masuk antrian porter: ${e.toString()}',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _handleStopPorterQueue() async {
|
||||
try {
|
||||
final userData = await PreferencesService.getUserData();
|
||||
final validUserId = await _porterQueueController.validateAndGetUserId(userData?.uid);
|
||||
if (validUserId == null) {
|
||||
SnackbarHelper.showError(
|
||||
'Gagal',
|
||||
_porterQueueController.error.value,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_porterQueueController.validatePorterQueueForDeletion()) {
|
||||
SnackbarHelper.showError(
|
||||
'Gagal',
|
||||
'Tidak ada antrian porter yang aktif.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
final confirm = await _showStopConfirmationDialog();
|
||||
|
||||
if (!confirm) return;
|
||||
_showLoadingDialog();
|
||||
|
||||
final porterId = _porterQueueController.currentPorter.value!.id!;
|
||||
final success = await _porterQueueController.deletePorterQueue(porterId);
|
||||
|
||||
if (Get.isDialogOpen == true) {
|
||||
Get.back();
|
||||
}
|
||||
|
||||
if (success) {
|
||||
SnackbarHelper.showSuccess(
|
||||
'Berhasil',
|
||||
'Anda telah berhenti dari antrian porter',
|
||||
);
|
||||
setState(() {});
|
||||
} else {
|
||||
SnackbarHelper.showError(
|
||||
'Gagal',
|
||||
'Gagal menghentikan antrian porter: ${_porterQueueController.error.value}',
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
if (Get.isDialogOpen == true) {
|
||||
Get.back();
|
||||
}
|
||||
|
||||
SnackbarHelper.showError(
|
||||
'Gagal',
|
||||
'Gagal menghentikan antrian porter: ${e.toString()}',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -250,10 +353,16 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
future: _userDataFuture,
|
||||
builder: (context, snapshot) {
|
||||
String userPorter = "Guest";
|
||||
String userId = '';
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
} else if (snapshot.hasData && snapshot.data?.name != null) {
|
||||
userPorter = snapshot.data!.name!;
|
||||
|
||||
if (snapshot.data?.uid != null) {
|
||||
userId = snapshot.data!.uid;
|
||||
_porterQueueController.loadCurrentPorter(userId);
|
||||
}
|
||||
}
|
||||
return SafeArea(
|
||||
child: Column(
|
||||
|
@ -306,25 +415,47 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
),
|
||||
SizedBox(height: 32.w),
|
||||
CustomeShadowCotainner(
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 6.h),
|
||||
decoration: BoxDecoration(
|
||||
color: PrimaryColors.primary200,
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
child: SvgPicture.asset(
|
||||
'assets/icons/ic_account.svg',
|
||||
width: 32.w,
|
||||
height: 32.h,
|
||||
),
|
||||
child: ZoomTapAnimation(
|
||||
child: GestureDetector(
|
||||
onTap: () => _porterQueueController.currentPorter.value != null
|
||||
? _handleStopPorterQueue()
|
||||
: _handlePorterQueueCreation(),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8.w, vertical: 6.h),
|
||||
decoration: BoxDecoration(
|
||||
color: _porterQueueController.currentPorter.value != null
|
||||
? RedColors.red100
|
||||
: PrimaryColors.primary200,
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
child: Obx(() => _porterQueueController.currentPorter.value != null
|
||||
? Icon(
|
||||
Icons.power_settings_new,
|
||||
color: Colors.red,
|
||||
size: 32.w,
|
||||
)
|
||||
: SvgPicture.asset(
|
||||
'assets/icons/ic_account.svg',
|
||||
width: 32.w,
|
||||
height: 32.h,
|
||||
)),
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
Obx(
|
||||
() => _porterQueueController.currentPorter.value != null
|
||||
? TypographyStyles.body(
|
||||
'Stop',
|
||||
color: GrayColors.gray800,
|
||||
)
|
||||
: TypographyStyles.body(
|
||||
'Mulai Antrian',
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 10.h),
|
||||
TypographyStyles.body(
|
||||
'Mulai Antrian',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
|
@ -338,42 +469,137 @@ class _HomeScreenState extends State<HomeScreen> {
|
|||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
Widget _buildAppbar(
|
||||
BuildContext context, {
|
||||
required String nameAvatar,
|
||||
required String nameUser,
|
||||
required String subTitle,
|
||||
VoidCallback? onTap,
|
||||
}) {
|
||||
return CustomeShadowCotainner(
|
||||
sizeRadius: 0.r,
|
||||
child: Row(
|
||||
children: [
|
||||
ProfileAvatar(fullName: nameAvatar),
|
||||
SizedBox(width: 16.w),
|
||||
Expanded(
|
||||
Future<bool> _showStopConfirmationDialog() async {
|
||||
return await Get.dialog<bool>(
|
||||
Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
TypographyStyles.h6(
|
||||
'Konfirmasi',
|
||||
color: GrayColors.gray800,
|
||||
),
|
||||
SizedBox(height: 16.h),
|
||||
Text(
|
||||
'Apakah Anda yakin ingin menghentikan layanan porter?',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 14.sp,
|
||||
color: GrayColors.gray600,
|
||||
),
|
||||
),
|
||||
SizedBox(height: 24.h),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextButton(
|
||||
onPressed: () => Get.back(result: false),
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: GrayColors.gray600,
|
||||
),
|
||||
child: Text('Batal'),
|
||||
),
|
||||
),
|
||||
SizedBox(width: 8.w),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () => Get.back(result: true),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: RedColors.red500,
|
||||
foregroundColor: Colors.white,
|
||||
),
|
||||
child: Text('Berhenti'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
) ??
|
||||
false;
|
||||
}
|
||||
|
||||
void _showLoadingDialog() {
|
||||
Get.dialog(
|
||||
Dialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
elevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(16.w),
|
||||
width: 80.w,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.r),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
TypographyStyles.h6(nameUser, color: GrayColors.gray800),
|
||||
SizedBox(height: 4.h),
|
||||
TypographyStyles.caption(
|
||||
subTitle,
|
||||
color: GrayColors.gray600,
|
||||
fontWeight: FontWeight.w400,
|
||||
CircularProgressIndicator(
|
||||
color: PrimaryColors.primary800,
|
||||
),
|
||||
SizedBox(height: 12.h),
|
||||
Text(
|
||||
'Memproses...',
|
||||
style: TextStyle(
|
||||
fontSize: 12.sp,
|
||||
color: GrayColors.gray600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
ZoomTapAnimation(
|
||||
child: IconButton(
|
||||
onPressed: onTap,
|
||||
icon: CustomeIcons.NotificationOutline(),
|
||||
),
|
||||
barrierDismissible: false,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildAppbar(
|
||||
BuildContext context, {
|
||||
required String nameAvatar,
|
||||
required String nameUser,
|
||||
required String subTitle,
|
||||
VoidCallback? onTap,
|
||||
}) {
|
||||
return CustomeShadowCotainner(
|
||||
sizeRadius: 0.r,
|
||||
child: Row(
|
||||
children: [
|
||||
ProfileAvatar(fullName: nameAvatar),
|
||||
SizedBox(width: 16.w),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TypographyStyles.h6(nameUser, color: GrayColors.gray800),
|
||||
SizedBox(height: 4.h),
|
||||
TypographyStyles.caption(
|
||||
subTitle,
|
||||
color: GrayColors.gray600,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
ZoomTapAnimation(
|
||||
child: IconButton(
|
||||
onPressed: onTap,
|
||||
icon: CustomeIcons.NotificationOutline(),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,6 +174,127 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||
}
|
||||
|
||||
Widget _buildPorterUI() {
|
||||
return Scaffold();
|
||||
return Scaffold(
|
||||
backgroundColor: GrayColors.gray50,
|
||||
appBar: BasicAppbarComponent(title: 'Profil'),
|
||||
body: FutureBuilder<UserData?>(
|
||||
future: _userDataFuture,
|
||||
builder: (context, snapshot) {
|
||||
String userName = "Guest";
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return Center(child: CircularProgressIndicator());
|
||||
} else if (snapshot.hasData && snapshot.data?.name != null) {
|
||||
userName = snapshot.data!.name!;
|
||||
}
|
||||
return SafeArea(
|
||||
child: Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 20.h),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
CustomeShadowCotainner(
|
||||
borderRadius: BorderRadius.circular(0.r),
|
||||
child: Row(
|
||||
children: [
|
||||
ProfileAvatar(fullName: userName),
|
||||
SizedBox(width: 16.w),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TypographyStyles.caption('Hi,', color: GrayColors.gray600, fontWeight: FontWeight.w400),
|
||||
TypographyStyles.body(userName, color: GrayColors.gray800),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20.h),
|
||||
CustomeShadowCotainner(
|
||||
borderRadius: BorderRadius.circular(0.r),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
TypographyStyles.h6('Pengaturan', color: GrayColors.gray800),
|
||||
SizedBox(height: 32.h),
|
||||
ProfileMenu(
|
||||
label: 'Lihat Profile',
|
||||
svgIcon: 'assets/icons/ic_profile.svg',
|
||||
onTap: () {},
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 20.h),
|
||||
child: Divider(thickness: 1, color: GrayColors.gray100),
|
||||
),
|
||||
ProfileMenu(
|
||||
label: 'Ganti Kata Sandi',
|
||||
svgIcon: 'assets/icons/ic_lock.svg',
|
||||
onTap: () {},
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 20.h),
|
||||
child: Divider(thickness: 1, color: GrayColors.gray100),
|
||||
),
|
||||
ProfileMenu(
|
||||
label: 'Logout',
|
||||
svgIcon: 'assets/icons/ic_logout.svg',
|
||||
onTap: () {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) {
|
||||
return AlertDialog(
|
||||
backgroundColor: Colors.white,
|
||||
title: TypographyStyles.body('Keluar', color: GrayColors.gray800),
|
||||
content: TypographyStyles.caption(
|
||||
'Apakah anda yakin untuk keluar dari akun ini?',
|
||||
color: GrayColors.gray600,
|
||||
fontWeight: FontWeight.w500,
|
||||
maxlines: 3,
|
||||
),
|
||||
actions: [
|
||||
ZoomTapAnimation(
|
||||
child: TextButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
child: TypographyStyles.caption(
|
||||
'Tidak',
|
||||
color: GrayColors.gray800,
|
||||
),
|
||||
),
|
||||
),
|
||||
ZoomTapAnimation(
|
||||
child: GestureDetector(
|
||||
onTap: () async {
|
||||
await PreferencesService.clearUserData();
|
||||
Navigator.of(context).pop();
|
||||
Get.offAllNamed(Routes.SPLASH);
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 30.w, vertical: 8.h),
|
||||
decoration: BoxDecoration(
|
||||
color: PrimaryColors.primary800,
|
||||
borderRadius: BorderRadius.circular(8.r),
|
||||
),
|
||||
child: TypographyStyles.caption('Ya', color: Colors.white),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:e_porter/domain/bindings/auth_binding.dart';
|
||||
import 'package:e_porter/domain/bindings/history_binding.dart';
|
||||
import 'package:e_porter/domain/bindings/navigation_binding.dart';
|
||||
import 'package:e_porter/domain/bindings/porter_queue_binding.dart';
|
||||
import 'package:e_porter/domain/bindings/porter_service_binding.dart';
|
||||
import 'package:e_porter/domain/bindings/profil_binding.dart';
|
||||
import 'package:e_porter/domain/bindings/search_flight_binding.dart';
|
||||
|
@ -42,6 +43,7 @@ class AppRoutes {
|
|||
bindings: [
|
||||
MainNavigationBinding(),
|
||||
HistoryBinding(),
|
||||
PorterQueueBinding(),
|
||||
],
|
||||
),
|
||||
GetPage(
|
||||
|
|
Loading…
Reference in New Issue