Feat: done page ticket_booking_step1
This commit is contained in:
parent
7b4506a256
commit
7c79dfab1e
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 @@
|
||||||
#Fri Mar 14 19:50:32 WIB 2025
|
#Sat Mar 15 19:23:50 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
|
||||||
|
|
|
@ -10,6 +10,7 @@ class ButtonFill extends StatelessWidget {
|
||||||
final Color? textColor;
|
final Color? textColor;
|
||||||
final VoidCallback? onTap;
|
final VoidCallback? onTap;
|
||||||
final bool isLoading;
|
final bool isLoading;
|
||||||
|
final Color? backgroundColor;
|
||||||
|
|
||||||
const ButtonFill({
|
const ButtonFill({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
@ -17,6 +18,7 @@ class ButtonFill extends StatelessWidget {
|
||||||
required this.textColor,
|
required this.textColor,
|
||||||
this.onTap,
|
this.onTap,
|
||||||
this.isLoading = false,
|
this.isLoading = false,
|
||||||
|
this.backgroundColor,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -27,8 +29,7 @@ class ButtonFill extends StatelessWidget {
|
||||||
child: ElevatedButton(
|
child: ElevatedButton(
|
||||||
onPressed: onTap,
|
onPressed: onTap,
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
backgroundColor:
|
backgroundColor: isLoading ? GrayColors.gray400 : (backgroundColor ?? PrimaryColors.primary800),
|
||||||
isLoading ? GrayColors.gray500 : PrimaryColors.primary800,
|
|
||||||
shape: RoundedRectangleBorder(
|
shape: RoundedRectangleBorder(
|
||||||
borderRadius: BorderRadius.circular(35.r),
|
borderRadius: BorderRadius.circular(35.r),
|
||||||
),
|
),
|
||||||
|
|
|
@ -16,6 +16,8 @@ class CardFlightInformation extends StatelessWidget {
|
||||||
final String seatClass;
|
final String seatClass;
|
||||||
final String? servicePorter;
|
final String? servicePorter;
|
||||||
final String passenger;
|
final String passenger;
|
||||||
|
final String? transiAirplane;
|
||||||
|
final String? stop;
|
||||||
|
|
||||||
const CardFlightInformation({
|
const CardFlightInformation({
|
||||||
Key? key,
|
Key? key,
|
||||||
|
@ -27,6 +29,8 @@ class CardFlightInformation extends StatelessWidget {
|
||||||
required this.seatClass,
|
required this.seatClass,
|
||||||
this.servicePorter,
|
this.servicePorter,
|
||||||
required this.passenger,
|
required this.passenger,
|
||||||
|
this.transiAirplane,
|
||||||
|
this.stop,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -39,12 +43,13 @@ class CardFlightInformation extends StatelessWidget {
|
||||||
SizedBox(height: 10.h),
|
SizedBox(height: 10.h),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
TypographyStyles.small(
|
if (stop != null && stop!.isNotEmpty) ...[
|
||||||
date,
|
TypographyStyles.small('${stop}', color: GrayColors.gray600, fontWeight: FontWeight.w400),
|
||||||
color: GrayColors.gray600,
|
SizedBox(width: 10.w),
|
||||||
letterSpacing: 0.2,
|
CircleAvatar(radius: 2.r, backgroundColor: Color(0xFFD9D9D9)),
|
||||||
fontWeight: FontWeight.w400,
|
SizedBox(width: 10.w),
|
||||||
),
|
],
|
||||||
|
TypographyStyles.small(date, color: GrayColors.gray600, fontWeight: FontWeight.w400),
|
||||||
SizedBox(width: 10.w),
|
SizedBox(width: 10.w),
|
||||||
CircleAvatar(radius: 2.r, backgroundColor: Color(0xFFD9D9D9)),
|
CircleAvatar(radius: 2.r, backgroundColor: Color(0xFFD9D9D9)),
|
||||||
SizedBox(width: 10.w),
|
SizedBox(width: 10.w),
|
||||||
|
@ -63,7 +68,13 @@ class CardFlightInformation extends StatelessWidget {
|
||||||
SizedBox(width: 10.w),
|
SizedBox(width: 10.w),
|
||||||
CustomeIcons.PlaneRightFilled(color: PrimaryColors.primary800),
|
CustomeIcons.PlaneRightFilled(color: PrimaryColors.primary800),
|
||||||
SizedBox(width: 10.w),
|
SizedBox(width: 10.w),
|
||||||
TypographyStyles.body(arrivalCity, color: GrayColors.gray800)
|
if (transiAirplane != null && transiAirplane!.isNotEmpty) ...[
|
||||||
|
TypographyStyles.body('${transiAirplane}', color: GrayColors.gray800),
|
||||||
|
SizedBox(width: 10.w),
|
||||||
|
CustomeIcons.PlaneRightFilled(color: PrimaryColors.primary800),
|
||||||
|
SizedBox(width: 10.w),
|
||||||
|
],
|
||||||
|
TypographyStyles.body(arrivalCity, color: GrayColors.gray800),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SizedBox(height: 4.h),
|
SizedBox(height: 4.h),
|
||||||
|
|
|
@ -203,6 +203,8 @@ class _HomeScreenState extends State<HomeScreen> {
|
||||||
color: GrayColors.gray600,
|
color: GrayColors.gray600,
|
||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 16.h),
|
||||||
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// ignore_for_file: deprecated_member_use
|
||||||
|
|
||||||
import 'package:e_porter/_core/component/appbar/appbar_component.dart';
|
import 'package:e_porter/_core/component/appbar/appbar_component.dart';
|
||||||
import 'package:e_porter/_core/component/button/button_fill.dart';
|
import 'package:e_porter/_core/component/button/button_fill.dart';
|
||||||
import 'package:e_porter/_core/component/button/switch_button.dart';
|
import 'package:e_porter/_core/component/button/switch_button.dart';
|
||||||
|
@ -9,6 +11,7 @@ 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/_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/domain/models/user_entity.dart';
|
||||||
import 'package:e_porter/presentation/controllers/profil_controller.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';
|
||||||
|
@ -40,6 +43,7 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
final ProfilController profilController = Get.find<ProfilController>();
|
final ProfilController profilController = Get.find<ProfilController>();
|
||||||
final currencyFormatter = NumberFormat.decimalPattern('id_ID');
|
final currencyFormatter = NumberFormat.decimalPattern('id_ID');
|
||||||
dynamic _loggedUser;
|
dynamic _loggedUser;
|
||||||
|
List<PassengerModel?> selectedPassengers = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
|
@ -53,6 +57,8 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
|
|
||||||
ticketController = Get.find<TicketController>();
|
ticketController = Get.find<TicketController>();
|
||||||
_flightFuture = ticketController.getFlightById(ticketId: ticketId, flightId: flightId);
|
_flightFuture = ticketController.getFlightById(ticketId: ticketId, flightId: flightId);
|
||||||
|
|
||||||
|
selectedPassengers = List.filled(passenger, null, growable: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loadPassengers() async {
|
Future<void> _loadPassengers() async {
|
||||||
|
@ -66,6 +72,14 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
logger.d('User ID: $userId');
|
logger.d('User ID: $userId');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isAllPassengersFilled() {
|
||||||
|
if (isToggled && _loggedUser != null) {
|
||||||
|
return selectedPassengers.skip(1).every((p) => p != null);
|
||||||
|
} else {
|
||||||
|
return selectedPassengers.every((p) => p != null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
@ -100,13 +114,15 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
CardFlightInformation(
|
CardFlightInformation(
|
||||||
date: '${ticketDate}',
|
date: ticketDate,
|
||||||
time: '$departureTime - $arrivalTime',
|
time: '$departureTime - $arrivalTime',
|
||||||
departureCity: '${flight.cityDeparture}',
|
departureCity: flight.cityDeparture,
|
||||||
arrivalCity: '${flight.cityArrival}',
|
arrivalCity: flight.cityArrival,
|
||||||
plane: '${flight.airLines} (${flight.code})',
|
plane: '${flight.airLines} (${flight.code})',
|
||||||
seatClass: '${flight.flightClass}',
|
seatClass: flight.flightClass,
|
||||||
passenger: '$passenger',
|
passenger: '$passenger',
|
||||||
|
transiAirplane: flight.transitAirplane,
|
||||||
|
stop: flight.stop,
|
||||||
),
|
),
|
||||||
SizedBox(height: 32.h),
|
SizedBox(height: 32.h),
|
||||||
TypographyStyles.h6('Detail Pemesanan', color: GrayColors.gray800),
|
TypographyStyles.h6('Detail Pemesanan', color: GrayColors.gray800),
|
||||||
|
@ -122,14 +138,19 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
bottomNavigationBar: CustomeShadowCotainner(
|
bottomNavigationBar: CustomeShadowCotainner(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.h),
|
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.h),
|
||||||
child: ButtonFill(
|
child: ButtonFill(
|
||||||
text: 'Lanjutkan',
|
text: 'Lanjutkan',
|
||||||
textColor: Colors.white,
|
textColor: Colors.white,
|
||||||
|
backgroundColor: isAllPassengersFilled() ? PrimaryColors.primary800 : GrayColors.gray400,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Get.toNamed(Routes.TICKETBOOKINGSTEP2);
|
if (!isAllPassengersFilled()) {
|
||||||
|
SnackbarHelper.showError('Error', 'Harap lengkapi slot penumpang');
|
||||||
|
} else {
|
||||||
|
Get.toNamed(Routes.TICKETBOOKINGSTEP2);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -208,186 +229,185 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
|
|
||||||
Widget _buildCardDetailPessenger() {
|
Widget _buildCardDetailPessenger() {
|
||||||
return Column(
|
return Column(
|
||||||
children: List.generate(
|
children: List.generate(
|
||||||
passenger,
|
passenger,
|
||||||
(index) {
|
(index) {
|
||||||
if (isToggled && index == 0 && _loggedUser != null) {
|
if (isToggled && index == 0 && _loggedUser != null) {
|
||||||
return Padding(
|
return _buildUserPassengerCard(_loggedUser);
|
||||||
padding: EdgeInsets.only(bottom: 16.h),
|
} else {
|
||||||
child: CustomeShadowCotainner(
|
final p = selectedPassengers[index];
|
||||||
child: Row(
|
if (p != null) {
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
return _buildSelectedPassengerCard(p, index);
|
||||||
children: [
|
} else {
|
||||||
Column(
|
return _buildEmptyPassengerCard(index);
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
}
|
||||||
children: [
|
}
|
||||||
TypographyStyles.body(
|
},
|
||||||
'${_loggedUser.name}',
|
),
|
||||||
color: GrayColors.gray800,
|
);
|
||||||
fontWeight: FontWeight.w500,
|
}
|
||||||
),
|
|
||||||
SizedBox(height: 4.h),
|
Widget _buildUserPassengerCard(dynamic user) {
|
||||||
TypographyStyles.caption(
|
return Padding(
|
||||||
"${_loggedUser.tipeId} - ${_loggedUser.noId}",
|
padding: EdgeInsets.only(bottom: 16.h),
|
||||||
color: GrayColors.gray800,
|
child: CustomeShadowCotainner(
|
||||||
fontWeight: FontWeight.w400,
|
child: Row(
|
||||||
)
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
],
|
children: [
|
||||||
),
|
Column(
|
||||||
],
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
),
|
children: [
|
||||||
|
TypographyStyles.body(
|
||||||
|
'${_loggedUser.name}',
|
||||||
|
color: GrayColors.gray800,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
SizedBox(height: 4.h),
|
||||||
|
TypographyStyles.caption(
|
||||||
|
"${_loggedUser.tipeId} - ${_loggedUser.noId}",
|
||||||
|
color: GrayColors.gray800,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
ZoomTapAnimation(
|
||||||
} else {
|
child: GestureDetector(
|
||||||
return Padding(
|
child: CustomeIcons.EditOutline(),
|
||||||
padding: EdgeInsets.only(bottom: 16.h),
|
onTap: () {
|
||||||
child: CustomeShadowCotainner(
|
Get.bottomSheet(
|
||||||
child: Row(
|
Padding(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
padding: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h),
|
||||||
children: [
|
child: Wrap(
|
||||||
TypographyStyles.body(
|
children: [
|
||||||
'Penumpang ${index + 1} (Dewasa)',
|
TitleShowModal(
|
||||||
color: GrayColors.gray800,
|
text: 'Informasi Penumpang',
|
||||||
fontWeight: FontWeight.w500,
|
onTap: () async {
|
||||||
),
|
if (Get.isBottomSheetOpen ?? false) {
|
||||||
ZoomTapAnimation(
|
Get.back();
|
||||||
child: GestureDetector(
|
}
|
||||||
child: CustomeIcons.EditOutline(),
|
await Future.delayed(Duration(seconds: 1));
|
||||||
onTap: () {
|
var result = await Get.toNamed(Routes.ADDPASSENGER);
|
||||||
Get.bottomSheet(
|
if (result == true) {
|
||||||
Padding(
|
_loadPassengers().then((_) => setState(() {}));
|
||||||
padding: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h),
|
}
|
||||||
child: Wrap(
|
},
|
||||||
children: [
|
),
|
||||||
TitleShowModal(
|
Obx(
|
||||||
text: 'Informasi Penumpang',
|
() {
|
||||||
onTap: () async {
|
if (profilController.passengerList.isEmpty) {
|
||||||
if (Get.isBottomSheetOpen ?? false) {
|
return Center(
|
||||||
Get.back();
|
child: TypographyStyles.body(
|
||||||
}
|
"Belum ada penumpang",
|
||||||
await Future.delayed(Duration(seconds: 1));
|
color: GrayColors.gray400,
|
||||||
var result = await Get.toNamed(Routes.ADDPASSENGER);
|
fontWeight: FontWeight.w500,
|
||||||
if (result == true) {
|
),
|
||||||
_loadPassengers().then((_) => setState(() {}));
|
);
|
||||||
// SnackbarHelper.showSuccess('Berhasil', 'Penumpang berhasil ditambahkan');
|
}
|
||||||
}
|
return ListView.builder(
|
||||||
},
|
itemCount: profilController.passengerList.length,
|
||||||
),
|
shrinkWrap: true,
|
||||||
Obx(
|
itemBuilder: (context, index) {
|
||||||
() {
|
final passenger = profilController.passengerList[index];
|
||||||
if (profilController.passengerList.isEmpty) {
|
logger.d("Passenger Models : ${passenger.noId}");
|
||||||
return Center(
|
return Padding(
|
||||||
child: TypographyStyles.body(
|
padding: EdgeInsets.only(top: 16.h),
|
||||||
"Belum ada penumpang",
|
child: _buildAddPassenger(
|
||||||
color: GrayColors.gray400,
|
context,
|
||||||
fontWeight: FontWeight.w500,
|
title: "${passenger.name}",
|
||||||
),
|
subTitle: "${passenger.typeId} - ${passenger.noId}",
|
||||||
);
|
onTap: () {
|
||||||
}
|
selectedPassengers[index] = passenger;
|
||||||
return ListView.builder(
|
Get.back();
|
||||||
itemCount: profilController.passengerList.length,
|
setState(() {});
|
||||||
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,
|
],
|
||||||
isScrollControlled: true,
|
),
|
||||||
shape: RoundedRectangleBorder(
|
|
||||||
borderRadius: BorderRadius.only(
|
|
||||||
topLeft: Radius.circular(10.r),
|
|
||||||
topRight: Radius.circular(10.r),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
// 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}",
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
)
|
backgroundColor: Colors.white,
|
||||||
],
|
isScrollControlled: true,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10.r),
|
||||||
|
topRight: Radius.circular(10.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildSelectedPassengerCard(PassengerModel p, int slotIndex) {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 16.h),
|
||||||
|
child: CustomeShadowCotainner(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
Column(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
TypographyStyles.body(
|
||||||
|
'${p.name}',
|
||||||
|
color: GrayColors.gray800,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
SizedBox(height: 4.h),
|
||||||
|
TypographyStyles.caption(
|
||||||
|
"${p.typeId} - ${p.noId}",
|
||||||
|
color: GrayColors.gray800,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
)
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
ZoomTapAnimation(
|
||||||
}
|
child: GestureDetector(
|
||||||
},
|
child: CustomeIcons.EditOutline(),
|
||||||
));
|
onTap: () {
|
||||||
|
_onEditPassenger(slotIndex);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildEmptyPassengerCard(int slotIndex) {
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: 16.h),
|
||||||
|
child: CustomeShadowCotainner(
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
children: [
|
||||||
|
TypographyStyles.body(
|
||||||
|
'Penumpang ${slotIndex + 1} (Dewasa)',
|
||||||
|
color: GrayColors.gray800,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
ZoomTapAnimation(
|
||||||
|
child: GestureDetector(
|
||||||
|
child: CustomeIcons.EditOutline(),
|
||||||
|
onTap: () {
|
||||||
|
_onEditPassenger(slotIndex);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAddPassenger(
|
Widget _buildAddPassenger(
|
||||||
|
@ -395,10 +415,11 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
required String title,
|
required String title,
|
||||||
required String subTitle,
|
required String subTitle,
|
||||||
VoidCallback? onTap,
|
VoidCallback? onTap,
|
||||||
|
bool enabled = true,
|
||||||
}) {
|
}) {
|
||||||
return ZoomTapAnimation(
|
return ZoomTapAnimation(
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: onTap,
|
onTap: enabled ? onTap : null,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.h),
|
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 10.h),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
|
@ -412,16 +433,95 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
|
||||||
Column(
|
Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
TypographyStyles.body(title, color: GrayColors.gray800),
|
TypographyStyles.body(title, color: enabled ? GrayColors.gray800 : GrayColors.gray300),
|
||||||
SizedBox(height: 4.h),
|
SizedBox(height: 4.h),
|
||||||
TypographyStyles.caption("KTP - ${subTitle}", color: GrayColors.gray800, fontWeight: FontWeight.w400)
|
TypographyStyles.caption(
|
||||||
|
"${subTitle}",
|
||||||
|
color: enabled ? GrayColors.gray800 : GrayColors.gray300,
|
||||||
|
fontWeight: FontWeight.w400,
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
SvgPicture.asset('assets/icons/ic_more _than.svg')
|
SvgPicture.asset(
|
||||||
|
'assets/icons/ic_more _than.svg',
|
||||||
|
color: enabled ? PrimaryColors.primary800 : GrayColors.gray300,
|
||||||
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onEditPassenger(int slotIndex) {
|
||||||
|
Get.bottomSheet(
|
||||||
|
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(() {}));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
Obx(
|
||||||
|
() {
|
||||||
|
final usedNoIds = selectedPassengers.where((p) => p != null).map((p) => p!.noId).toSet();
|
||||||
|
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, pIndex) {
|
||||||
|
final passenger = profilController.passengerList[pIndex];
|
||||||
|
final isUsed = usedNoIds.contains(passenger.noId);
|
||||||
|
logger.d("Passenger Models : ${passenger.noId}");
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.only(top: 16.h),
|
||||||
|
child: _buildAddPassenger(
|
||||||
|
context,
|
||||||
|
title: "${passenger.name}",
|
||||||
|
subTitle: "${passenger.typeId} - ${passenger.noId}",
|
||||||
|
enabled: !isUsed,
|
||||||
|
onTap: isUsed
|
||||||
|
? null
|
||||||
|
: () {
|
||||||
|
selectedPassengers[slotIndex] = passenger;
|
||||||
|
Get.back();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
backgroundColor: Colors.white,
|
||||||
|
isScrollControlled: true,
|
||||||
|
shape: RoundedRectangleBorder(
|
||||||
|
borderRadius: BorderRadius.only(
|
||||||
|
topLeft: Radius.circular(10.r),
|
||||||
|
topRight: Radius.circular(10.r),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue