Feat: add post data for add passenger screen
This commit is contained in:
parent
e447c93584
commit
7b4506a256
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because one or more lines are too long
|
@ -1,4 +1,4 @@
|
||||||
#Thu Mar 13 10:11:24 WIB 2025
|
#Fri Mar 14 19:50:32 WIB 2025
|
||||||
base.0=D\:\\Flutter\\Flutter Project\\e_porter\\build\\app\\intermediates\\dex\\debug\\mergeExtDexDebug\\classes.dex
|
base.0=D\:\\Flutter\\Flutter Project\\e_porter\\build\\app\\intermediates\\dex\\debug\\mergeExtDexDebug\\classes.dex
|
||||||
base.1=D\:\\Flutter\\Flutter Project\\e_porter\\build\\app\\intermediates\\dex\\debug\\mergeLibDexDebug\\0\\classes.dex
|
base.1=D\:\\Flutter\\Flutter Project\\e_porter\\build\\app\\intermediates\\dex\\debug\\mergeLibDexDebug\\0\\classes.dex
|
||||||
base.2=D\:\\Flutter\\Flutter Project\\e_porter\\build\\app\\intermediates\\dex\\debug\\mergeProjectDexDebug\\0\\classes.dex
|
base.2=D\:\\Flutter\\Flutter Project\\e_porter\\build\\app\\intermediates\\dex\\debug\\mergeProjectDexDebug\\0\\classes.dex
|
||||||
|
|
|
@ -22,4 +22,20 @@ class ProfilRepositoryImpl implements ProfilRepository {
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<List<PassengerModel>> getPassengerById(String userId) async {
|
||||||
|
try {
|
||||||
|
QuerySnapshot querySnapshot = await _firestore
|
||||||
|
.collection('users')
|
||||||
|
.doc(userId)
|
||||||
|
.collection('passenger')
|
||||||
|
.get();
|
||||||
|
return querySnapshot.docs
|
||||||
|
.map((doc) => PassengerModel.fromMap(doc.data() as Map<String, dynamic>))
|
||||||
|
.toList();
|
||||||
|
} catch (e) {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -13,8 +13,12 @@ class ProfilBinding extends Bindings {
|
||||||
|
|
||||||
// Injeksi use case, menggunakan repository yang telah di-inject
|
// Injeksi use case, menggunakan repository yang telah di-inject
|
||||||
Get.lazyPut(() => CreatePassengerUseCase(Get.find()));
|
Get.lazyPut(() => CreatePassengerUseCase(Get.find()));
|
||||||
|
Get.lazyPut(() => GetPassengerByIdUseCase(Get.find()));
|
||||||
|
|
||||||
// Injeksi controller, menggunakan use case yang sudah tersedia
|
// Injeksi controller, menggunakan use case yang sudah tersedia
|
||||||
Get.lazyPut(() => ProfilController(createPassengerUseCase: Get.find()));
|
Get.lazyPut(() => ProfilController(
|
||||||
|
createPassengerUseCase: Get.find(),
|
||||||
|
getPassengerByIdUseCase: Get.find(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -5,4 +5,6 @@ abstract class ProfilRepository {
|
||||||
required String userId,
|
required String userId,
|
||||||
required PassengerModel passenger,
|
required PassengerModel passenger,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Future<List<PassengerModel>> getPassengerById(String userId);
|
||||||
}
|
}
|
|
@ -10,10 +10,19 @@ class CreatePassengerUseCase {
|
||||||
required String userId,
|
required String userId,
|
||||||
required PassengerModel passenger,
|
required PassengerModel passenger,
|
||||||
}) async {
|
}) async {
|
||||||
// Lakukan validasi atau logika bisnis lain jika diperlukan
|
|
||||||
await profilRepository.createPassenger(
|
await profilRepository.createPassenger(
|
||||||
userId: userId,
|
userId: userId,
|
||||||
passenger: passenger,
|
passenger: passenger,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class GetPassengerByIdUseCase {
|
||||||
|
final ProfilRepository profilRepository;
|
||||||
|
|
||||||
|
GetPassengerByIdUseCase(this.profilRepository);
|
||||||
|
|
||||||
|
Future<List<PassengerModel>> call(String userId) async {
|
||||||
|
return await profilRepository.getPassengerById(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import 'package:e_porter/_core/service/logger_service.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
import '../../domain/models/user_entity.dart';
|
import '../../domain/models/user_entity.dart';
|
||||||
|
@ -5,8 +6,11 @@ import '../../domain/usecases/profil_usecase.dart';
|
||||||
|
|
||||||
class ProfilController extends GetxController {
|
class ProfilController extends GetxController {
|
||||||
final CreatePassengerUseCase createPassengerUseCase;
|
final CreatePassengerUseCase createPassengerUseCase;
|
||||||
|
final GetPassengerByIdUseCase getPassengerByIdUseCase;
|
||||||
|
|
||||||
ProfilController({required this.createPassengerUseCase});
|
var passengerList = <PassengerModel>[].obs;
|
||||||
|
|
||||||
|
ProfilController({required this.createPassengerUseCase, required this.getPassengerByIdUseCase});
|
||||||
|
|
||||||
Future<void> addPassenger({
|
Future<void> addPassenger({
|
||||||
required String userId,
|
required String userId,
|
||||||
|
@ -26,4 +30,13 @@ class ProfilController extends GetxController {
|
||||||
passenger: passenger,
|
passenger: passenger,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> fetchPassangerById(String userId) async {
|
||||||
|
try {
|
||||||
|
List<PassengerModel> list = await getPassengerByIdUseCase(userId);
|
||||||
|
passengerList.assignAll(list);
|
||||||
|
} catch (e) {
|
||||||
|
logger.e("Error fetching passengers: $e");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -7,7 +7,9 @@ import 'package:e_porter/_core/constants/colors.dart';
|
||||||
import 'package:e_porter/_core/constants/typography.dart';
|
import 'package:e_porter/_core/constants/typography.dart';
|
||||||
import 'package:e_porter/_core/service/logger_service.dart';
|
import 'package:e_porter/_core/service/logger_service.dart';
|
||||||
import 'package:e_porter/_core/service/preferences_service.dart';
|
import 'package:e_porter/_core/service/preferences_service.dart';
|
||||||
|
import 'package:e_porter/_core/utils/snackbar/snackbar_helper.dart';
|
||||||
import 'package:e_porter/domain/models/ticket_model.dart';
|
import 'package:e_porter/domain/models/ticket_model.dart';
|
||||||
|
import 'package:e_porter/presentation/controllers/profil_controller.dart';
|
||||||
import 'package:e_porter/presentation/controllers/ticket_controller.dart';
|
import 'package:e_porter/presentation/controllers/ticket_controller.dart';
|
||||||
import 'package:e_porter/presentation/screens/home/component/card_flight_information.dart';
|
import 'package:e_porter/presentation/screens/home/component/card_flight_information.dart';
|
||||||
import 'package:e_porter/presentation/screens/home/component/title_show_modal.dart';
|
import 'package:e_porter/presentation/screens/home/component/title_show_modal.dart';
|
||||||
|
@ -35,12 +37,14 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
late final int passenger;
|
late final int passenger;
|
||||||
late Future<FlightModel> _flightFuture;
|
late Future<FlightModel> _flightFuture;
|
||||||
late final TicketController ticketController;
|
late final TicketController ticketController;
|
||||||
|
final ProfilController profilController = Get.find<ProfilController>();
|
||||||
final currencyFormatter = NumberFormat.decimalPattern('id_ID');
|
final currencyFormatter = NumberFormat.decimalPattern('id_ID');
|
||||||
dynamic _loggedUser;
|
dynamic _loggedUser;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
_loadPassengers();
|
||||||
final args = Get.arguments as Map<String, dynamic>;
|
final args = Get.arguments as Map<String, dynamic>;
|
||||||
ticketId = args['ticketId'];
|
ticketId = args['ticketId'];
|
||||||
flightId = args['flightId'];
|
flightId = args['flightId'];
|
||||||
|
@ -51,6 +55,17 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
_flightFuture = ticketController.getFlightById(ticketId: ticketId, flightId: flightId);
|
_flightFuture = ticketController.getFlightById(ticketId: ticketId, flightId: flightId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _loadPassengers() async {
|
||||||
|
final userData = await PreferencesService.getUserData();
|
||||||
|
if (userData == null || userData.uid.isEmpty) {
|
||||||
|
SnackbarHelper.showError('Error', 'User ID tidak ditemukan, silakan login kembali');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final userId = userData.uid;
|
||||||
|
await profilController.fetchPassangerById(userId);
|
||||||
|
logger.d('User ID: $userId');
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -219,38 +234,6 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
ZoomTapAnimation(
|
|
||||||
child: GestureDetector(
|
|
||||||
child: CustomeIcons.EditOutline(),
|
|
||||||
onTap: () {
|
|
||||||
showModalBottomSheet(
|
|
||||||
context: context,
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
isScrollControlled: true,
|
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.only(
|
|
||||||
topLeft: Radius.circular(10.r),
|
|
||||||
topRight: Radius.circular(10.r),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
builder: (context) {
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
||||||
child: Wrap(
|
|
||||||
children: [
|
|
||||||
TitleShowModal(
|
|
||||||
text: 'Informasi Penumpang',
|
|
||||||
onTap: () {},
|
|
||||||
),
|
|
||||||
_buildAddPassenger(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -271,8 +254,57 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
child: CustomeIcons.EditOutline(),
|
child: CustomeIcons.EditOutline(),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
showModalBottomSheet(
|
Get.bottomSheet(
|
||||||
context: context,
|
Padding(
|
||||||
|
padding: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h),
|
||||||
|
child: Wrap(
|
||||||
|
children: [
|
||||||
|
TitleShowModal(
|
||||||
|
text: 'Informasi Penumpang',
|
||||||
|
onTap: () async {
|
||||||
|
if (Get.isBottomSheetOpen ?? false) {
|
||||||
|
Get.back();
|
||||||
|
}
|
||||||
|
await Future.delayed(Duration(seconds: 1));
|
||||||
|
var result = await Get.toNamed(Routes.ADDPASSENGER);
|
||||||
|
if (result == true) {
|
||||||
|
_loadPassengers().then((_) => setState(() {}));
|
||||||
|
// SnackbarHelper.showSuccess('Berhasil', 'Penumpang berhasil ditambahkan');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Obx(
|
||||||
|
() {
|
||||||
|
if (profilController.passengerList.isEmpty) {
|
||||||
|
return Center(
|
||||||
|
child: TypographyStyles.body(
|
||||||
|
"Belum ada penumpang",
|
||||||
|
color: GrayColors.gray400,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: profilController.passengerList.length,
|
||||||
|
shrinkWrap: true,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final passenger = profilController.passengerList[index];
|
||||||
|
logger.d("Passenger Models : ${passenger.noId}");
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(top: 16.h),
|
||||||
|
child: _buildAddPassenger(
|
||||||
|
context,
|
||||||
|
title: "${passenger.name}",
|
||||||
|
subTitle: "${passenger.noId}",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
backgroundColor: Colors.white,
|
backgroundColor: Colors.white,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
|
@ -281,23 +313,71 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
topRight: Radius.circular(10.r),
|
topRight: Radius.circular(10.r),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
builder: (context) {
|
|
||||||
return Padding(
|
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16.w),
|
|
||||||
child: Wrap(
|
|
||||||
children: [
|
|
||||||
TitleShowModal(
|
|
||||||
text: 'Informasi Penumpang',
|
|
||||||
onTap: () {
|
|
||||||
Get.toNamed(Routes.ADDPASSENGER);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
_buildAddPassenger(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
|
// showModalBottomSheet(
|
||||||
|
// context: context,
|
||||||
|
// backgroundColor: Colors.white,
|
||||||
|
// isScrollControlled: true,
|
||||||
|
// shape: RoundedRectangleBorder(
|
||||||
|
// borderRadius: BorderRadius.only(
|
||||||
|
// topLeft: Radius.circular(10.r),
|
||||||
|
// topRight: Radius.circular(10.r),
|
||||||
|
// ),
|
||||||
|
// ),
|
||||||
|
// builder: (context) {
|
||||||
|
// return Padding(
|
||||||
|
// padding: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h),
|
||||||
|
// child: Wrap(
|
||||||
|
// children: [
|
||||||
|
// TitleShowModal(
|
||||||
|
// text: 'Informasi Penumpang',
|
||||||
|
// onTap: () {
|
||||||
|
// Navigator.pop(context);
|
||||||
|
// Future.delayed(Duration(milliseconds: 300), () {
|
||||||
|
// Get.toNamed(Routes.ADDPASSENGER)?.then((result) {
|
||||||
|
// if (result == true) {
|
||||||
|
// _loadPassengers().then((_) => setState(() {}));
|
||||||
|
// SnackbarHelper.showSuccess('Berhasil', 'Penumpang berhasil ditambahkan');
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// SizedBox(height: 16.h),
|
||||||
|
// Obx(
|
||||||
|
// () {
|
||||||
|
// if (profilController.passengerList.isEmpty) {
|
||||||
|
// return Center(
|
||||||
|
// child: TypographyStyles.body(
|
||||||
|
// "Belum ada penumpang",
|
||||||
|
// color: GrayColors.gray400,
|
||||||
|
// fontWeight: FontWeight.w500,
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// return ListView.builder(
|
||||||
|
// itemCount: profilController.passengerList.length,
|
||||||
|
// shrinkWrap: true,
|
||||||
|
// itemBuilder: (context, index) {
|
||||||
|
// final passenger = profilController.passengerList[index];
|
||||||
|
// logger.d("Passenger Models : ${passenger.noId}");
|
||||||
|
// return Padding(
|
||||||
|
// padding: EdgeInsets.only(top: 16.h),
|
||||||
|
// child: _buildAddPassenger(
|
||||||
|
// context,
|
||||||
|
// title: "${passenger.name}",
|
||||||
|
// subTitle: "${passenger.noId}",
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// ),
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// },
|
||||||
|
// );
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
@ -310,30 +390,38 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAddPassenger() {
|
Widget _buildAddPassenger(
|
||||||
return Padding(
|
BuildContext context, {
|
||||||
padding: EdgeInsets.symmetric(vertical: 16.h),
|
required String title,
|
||||||
|
required String subTitle,
|
||||||
|
VoidCallback? onTap,
|
||||||
|
}) {
|
||||||
|
return ZoomTapAnimation(
|
||||||
|
child: GestureDetector(
|
||||||
|
onTap: onTap,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h),
|
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.h),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: GrayColors.gray50,
|
color: GrayColors.gray50,
|
||||||
border: Border.all(width: 1.w, color: GrayColors.gray200),
|
border: Border.all(width: 1.w, color: GrayColors.gray200),
|
||||||
borderRadius: BorderRadius.circular(10.r)),
|
borderRadius: BorderRadius.circular(10.r),
|
||||||
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
TypographyStyles.body("Muhammad Al Kahfi", color: GrayColors.gray800),
|
TypographyStyles.body(title, color: GrayColors.gray800),
|
||||||
SizedBox(height: 4.h),
|
SizedBox(height: 4.h),
|
||||||
TypographyStyles.caption("KTP - 3571", color: GrayColors.gray800, fontWeight: FontWeight.w400)
|
TypographyStyles.caption("KTP - ${subTitle}", color: GrayColors.gray800, fontWeight: FontWeight.w400)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SvgPicture.asset('assets/icons/ic_more _than.svg')
|
SvgPicture.asset('assets/icons/ic_more _than.svg')
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,7 @@ class _AddPassengerScreenState extends State<AddPassengerScreen> {
|
||||||
|
|
||||||
SnackbarHelper.showSuccess('Sukses', 'Berhasil menambahkan penumpang baru');
|
SnackbarHelper.showSuccess('Sukses', 'Berhasil menambahkan penumpang baru');
|
||||||
logger.d("Berhasil menambah penumpang: {name: $name, typeId: $typeId, noId: $noId, gender: $gender}");
|
logger.d("Berhasil menambah penumpang: {name: $name, typeId: $typeId, noId: $noId, gender: $gender}");
|
||||||
|
Navigator.pop(context, true);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
SnackbarHelper.showError('Error', 'Gagal menambahkan penumpang baru: $e');
|
SnackbarHelper.showError('Error', 'Gagal menambahkan penumpang baru: $e');
|
||||||
logger.e("Gagal menambah penumpang: $e");
|
logger.e("Gagal menambah penumpang: $e");
|
||||||
|
|
|
@ -89,6 +89,7 @@ class AppRoutes {
|
||||||
GetPage(
|
GetPage(
|
||||||
name: Routes.TICKETBOOKINGSTEP1,
|
name: Routes.TICKETBOOKINGSTEP1,
|
||||||
page: () => TicketBookingStep1Screen(),
|
page: () => TicketBookingStep1Screen(),
|
||||||
|
binding: ProfilBinding(),
|
||||||
),
|
),
|
||||||
GetPage(
|
GetPage(
|
||||||
name: Routes.TICKETBOOKINGSTEP2,
|
name: Routes.TICKETBOOKINGSTEP2,
|
||||||
|
|
Loading…
Reference in New Issue