Feat: Finishing flow booking tickets and UI boarding pass for transit tickets category

This commit is contained in:
orangdeso 2025-05-10 02:47:47 +07:00
parent ded8ce37b8
commit 7a2b8db157
15 changed files with 223 additions and 96 deletions

View File

@ -680,7 +680,7 @@
"languageVersion": "3.4" "languageVersion": "3.4"
} }
], ],
"generated": "2025-05-07T08:39:04.087158Z", "generated": "2025-05-09T09:48:57.570155Z",
"generator": "pub", "generator": "pub",
"generatorVersion": "3.5.0", "generatorVersion": "3.5.0",
"flutterRoot": "file:///D:/Flutter/flutter_sdk/flutter_3.24.0", "flutterRoot": "file:///D:/Flutter/flutter_sdk/flutter_3.24.0",

View File

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:cloud_firestore/cloud_firestore.dart';
import '../../domain/models/ticket_model.dart'; import '../../domain/models/ticket_model.dart';
import '../../domain/repositories/ticket_repository.dart'; import '../../domain/repositories/ticket_repository.dart';
@ -12,27 +14,35 @@ class TicketRepositoryImpl implements TicketRepository {
required String from, required String from,
required String to, required String to,
required DateTime leavingDate, required DateTime leavingDate,
String? seatClass,
}) async { }) async {
final collection = firestore.collection('tickets'); // final collection = firestore.collection('tickets');
// final startOfDay = DateTime(leavingDate.year, leavingDate.month, leavingDate.day);
// final endOfDay = startOfDay.add(Duration(days: 1));
// final snapshot = await collection
// .where('from', isEqualTo: from)
// .where('to', isEqualTo: to)
// .where('leavingDate', isGreaterThanOrEqualTo: Timestamp.fromDate(startOfDay))
// .where('leavingDate', isLessThan: Timestamp.fromDate(endOfDay))
// .get();
// snapshot.docs.forEach((doc) {});
// Normalisasi tanggal: ambil awal hari dan akhir hari untuk tanggal yang dicari
final startOfDay = DateTime(leavingDate.year, leavingDate.month, leavingDate.day); final startOfDay = DateTime(leavingDate.year, leavingDate.month, leavingDate.day);
final endOfDay = startOfDay.add(Duration(days: 1)); final endOfDay = startOfDay.add(Duration(days: 1));
// logger.d("Fetching tickets with parameters: from = $from, to = $to, leavingDate between = ${Timestamp.fromDate(startOfDay)} and ${Timestamp.fromDate(endOfDay)}"); log("Fetching tickets: from=$from, to=$to, leavingDate∈[$startOfDay $endOfDay]");
final snapshot = await collection final snapshot = await firestore
.collection('tickets')
.where('from', isEqualTo: from) .where('from', isEqualTo: from)
.where('to', isEqualTo: to) .where('to', isEqualTo: to)
.where('leavingDate', isGreaterThanOrEqualTo: Timestamp.fromDate(startOfDay)) .where('leavingDate', isGreaterThanOrEqualTo: Timestamp.fromDate(startOfDay))
.where('leavingDate', isLessThan: Timestamp.fromDate(endOfDay)) .where('leavingDate', isLessThan: Timestamp.fromDate(endOfDay))
.get(); .get();
// logger.d("Number of tickets found: ${snapshot.docs.length}");
snapshot.docs.forEach((doc) {
// logger.d("Doc ID: ${doc.id} => ${doc.data()}");
});
return snapshot.docs.map((doc) => TicketModel.fromDocument(doc)).toList(); return snapshot.docs.map((doc) => TicketModel.fromDocument(doc)).toList();
} }
@ -49,10 +59,7 @@ class TicketRepositoryImpl implements TicketRepository {
} }
final snapshot = await query.get(); final snapshot = await query.get();
// logger.d("Number of flights found for ticket $ticketId with seatClass '$flightClass': ${snapshot.docs.length}"); snapshot.docs.forEach((doc) {});
snapshot.docs.forEach((doc) {
// logger.d("Flight Doc ID: ${doc.id} => ${doc.data()}");
});
return snapshot.docs.map((doc) => FlightModel.fromDocument(doc)).toList(); return snapshot.docs.map((doc) => FlightModel.fromDocument(doc)).toList();
} }
@ -62,12 +69,7 @@ class TicketRepositoryImpl implements TicketRepository {
required String ticketId, required String ticketId,
required String flightId, required String flightId,
}) async { }) async {
final doc = await firestore final doc = await firestore.collection('tickets').doc(ticketId).collection('flights').doc(flightId).get();
.collection('tickets')
.doc(ticketId)
.collection('flights')
.doc(flightId)
.get();
// logger.d("getFlightById - TicketID: $ticketId, FlightID: $flightId, Data: ${doc.data()}"); // logger.d("getFlightById - TicketID: $ticketId, FlightID: $flightId, Data: ${doc.data()}");

View File

@ -46,6 +46,9 @@ class FlightModel {
final String codeArrival; final String codeArrival;
final DateTime departureTime; final DateTime departureTime;
final DateTime arrivalTime; final DateTime arrivalTime;
final DateTime? startDateTransit;
final DateTime? endDateTransit;
final String cityTransit;
final String transitAirplane; final String transitAirplane;
final String stop; final String stop;
final int price; final int price;
@ -64,6 +67,9 @@ class FlightModel {
required this.codeArrival, required this.codeArrival,
required this.departureTime, required this.departureTime,
required this.arrivalTime, required this.arrivalTime,
this.startDateTransit,
this.endDateTransit,
required this.cityTransit,
required this.transitAirplane, required this.transitAirplane,
required this.stop, required this.stop,
required this.price, required this.price,
@ -93,6 +99,9 @@ class FlightModel {
codeArrival: data['codeArrival'] ?? '', codeArrival: data['codeArrival'] ?? '',
departureTime: (data['dateDeparture'] as Timestamp).toDate(), departureTime: (data['dateDeparture'] as Timestamp).toDate(),
arrivalTime: (data['dateArrival'] as Timestamp).toDate(), arrivalTime: (data['dateArrival'] as Timestamp).toDate(),
startDateTransit: (data['startDateTransit'] as Timestamp?)?.toDate(),
endDateTransit: (data['endDateTransit'] as Timestamp?)?.toDate(),
cityTransit: data['cityTransit'] ?? '',
transitAirplane: data['transitAirplane'] ?? '', transitAirplane: data['transitAirplane'] ?? '',
stop: data['stop'] ?? '', stop: data['stop'] ?? '',
price: data['price'] ?? 0, price: data['price'] ?? 0,
@ -113,6 +122,9 @@ class FlightModel {
'codeArrival': codeArrival, 'codeArrival': codeArrival,
'dateDeparture': Timestamp.fromDate(departureTime), 'dateDeparture': Timestamp.fromDate(departureTime),
'dateArrival': Timestamp.fromDate(arrivalTime), 'dateArrival': Timestamp.fromDate(arrivalTime),
'startDateTransit': Timestamp.fromDate(startDateTransit!),
'endDateTransit': Timestamp.fromDate(endDateTransit!),
'cityTransit': cityTransit,
'transitAirplane': transitAirplane, 'transitAirplane': transitAirplane,
'stop': stop, 'stop': stop,
'price': price, 'price': price,

View File

@ -26,7 +26,9 @@ class CardBoardingPass extends StatelessWidget {
final String? arrivalCode; final String? arrivalCode;
final String? departurePlane; final String? departurePlane;
final String? arrivalPlane; final String? arrivalPlane;
final String? transitCity;
final String? transitPlane; final String? transitPlane;
final String? transitCode;
final String? transitStartDate; final String? transitStartDate;
final String? transitEndDate; final String? transitEndDate;
final String? departureTime; final String? departureTime;
@ -55,7 +57,9 @@ class CardBoardingPass extends StatelessWidget {
this.arrivalCode, this.arrivalCode,
this.departurePlane, this.departurePlane,
this.arrivalPlane, this.arrivalPlane,
this.transitCity,
this.transitPlane, this.transitPlane,
this.transitCode,
this.transitStartDate, this.transitStartDate,
this.transitEndDate, this.transitEndDate,
this.departureTime, this.departureTime,
@ -157,12 +161,14 @@ class CardBoardingPass extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
TypographyStyles.caption("$departureTime", color: GrayColors.gray800), TypographyStyles.caption("$departureTime", color: GrayColors.gray800),
TypographyStyles.small("$departureDate", color: GrayColors.gray600, fontWeight: FontWeight.w400), TypographyStyles.small("$departureDate",
color: GrayColors.gray600, fontWeight: FontWeight.w400),
SizedBox(height: 20.h), SizedBox(height: 20.h),
TypographyStyles.small("$duration", color: GrayColors.gray600, fontWeight: FontWeight.w400), TypographyStyles.small("$duration", color: GrayColors.gray600, fontWeight: FontWeight.w400),
SizedBox(height: 20.h), SizedBox(height: 20.h),
TypographyStyles.caption("$arrivalTime", color: GrayColors.gray800), TypographyStyles.caption("$arrivalTime", color: GrayColors.gray800),
TypographyStyles.small("$arrivalDate", color: GrayColors.gray600, fontWeight: FontWeight.w400), TypographyStyles.small("$arrivalDate",
color: GrayColors.gray600, fontWeight: FontWeight.w400),
], ],
), ),
SizedBox(width: 20.w), SizedBox(width: 20.w),
@ -180,7 +186,23 @@ class CardBoardingPass extends StatelessWidget {
maxlines: 2, maxlines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
SizedBox(height: 58.h), SizedBox(height: 20.h),
if (transitCity != null &&
transitCity!.isNotEmpty &&
transitCode != null &&
transitCode!.isNotEmpty &&
transitPlane != null &&
transitPlane!.isNotEmpty) ...[
TypographyStyles.caption("$transitCity ($transitCode)", color: GrayColors.gray800),
TypographyStyles.caption(
"$transitPlane",
color: GrayColors.gray600,
fontWeight: FontWeight.w400,
maxlines: 2,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 20.h),
],
TypographyStyles.caption("$arrivalCity ($arrivalCode)", color: GrayColors.gray800), TypographyStyles.caption("$arrivalCity ($arrivalCode)", color: GrayColors.gray800),
TypographyStyles.caption( TypographyStyles.caption(
"$arrivalPlane", "$arrivalPlane",
@ -188,7 +210,7 @@ class CardBoardingPass extends StatelessWidget {
fontWeight: FontWeight.w400, fontWeight: FontWeight.w400,
maxlines: 2, maxlines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
) ),
], ],
), ),
) )

View File

@ -1,5 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
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/constants/colors.dart'; import 'package:e_porter/_core/constants/colors.dart';
import 'package:e_porter/_core/utils/formatter/date_helper.dart'; import 'package:e_porter/_core/utils/formatter/date_helper.dart';
@ -283,13 +282,14 @@ class _BoardingPassScreenState extends State<BoardingPassScreen> with SingleTick
arrivalCode: flightDetails['codeArrival'], arrivalCode: flightDetails['codeArrival'],
departurePlane: departurePlane, departurePlane: departurePlane,
arrivalPlane: arrivalPlane, arrivalPlane: arrivalPlane,
transitCity: flightDetails['cityTransit'],
transitCode: flightDetails['codeTransit'],
transitPlane: flightDetails['transitAirplane'],
onTap: () { onTap: () {
final argument = { final argument = {
'id_transaction': transaction.id, 'id_transaction': transaction.id,
'id_ticket': transaction.ticketId, 'id_ticket': transaction.ticketId,
}; };
log('Arrival Time: $arrivalTime');
log('Departure Time: $departureTime');
Get.toNamed(Routes.DETAILTICKET, arguments: argument); Get.toNamed(Routes.DETAILTICKET, arguments: argument);
}, },

View File

@ -140,8 +140,11 @@ class _DetailTicketScreenState extends State<DetailTicketScreen> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
TypographyStyles.caption(departureTime, color: GrayColors.gray800), TypographyStyles.caption(departureTime, color: GrayColors.gray800),
TypographyStyles.small(departureDate, TypographyStyles.small(
color: GrayColors.gray600, fontWeight: FontWeight.w400), departureDate,
color: GrayColors.gray600,
fontWeight: FontWeight.w400,
),
SizedBox(height: 20.h), SizedBox(height: 20.h),
TypographyStyles.small(duration, color: GrayColors.gray600, fontWeight: FontWeight.w400), TypographyStyles.small(duration, color: GrayColors.gray600, fontWeight: FontWeight.w400),
SizedBox(height: 20.h), SizedBox(height: 20.h),
@ -152,35 +155,16 @@ class _DetailTicketScreenState extends State<DetailTicketScreen> {
SizedBox(width: 20.w), SizedBox(width: 20.w),
SvgPicture.asset('assets/images/garis.svg', height: 100.h), SvgPicture.asset('assets/images/garis.svg', height: 100.h),
SizedBox(width: 20.w), SizedBox(width: 20.w),
Expanded( _buildDataBandara(
child: Column( titleDeparture:
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TypographyStyles.caption(
"${transaction.flightDetails['cityDeparture']} (${transaction.flightDetails['codeDeparture']})", "${transaction.flightDetails['cityDeparture']} (${transaction.flightDetails['codeDeparture']})",
color: GrayColors.gray800, planeDeparture: "${transaction.bandaraDetails['departure']?['name']}",
), titleTransit:
TypographyStyles.caption( "${transaction.flightDetails['cityTransit']} (${transaction.flightDetails['codeTransit']})",
"${transaction.bandaraDetails['departure']?['name']}", planeTransit: transaction.flightDetails['transitAirplane'],
color: GrayColors.gray600, titleArrival:
fontWeight: FontWeight.w400,
maxlines: 2,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 58.h),
TypographyStyles.caption(
"${transaction.flightDetails['cityArrival']} (${transaction.flightDetails['codeArrival']})", "${transaction.flightDetails['cityArrival']} (${transaction.flightDetails['codeArrival']})",
color: GrayColors.gray800, planeArrival: "${transaction.bandaraDetails['arrival']?['name']}",
),
TypographyStyles.caption(
"${transaction.bandaraDetails['arrival']?['name']}",
color: GrayColors.gray600,
fontWeight: FontWeight.w400,
maxlines: 2,
overflow: TextOverflow.ellipsis,
)
],
),
) )
], ],
), ),
@ -313,6 +297,51 @@ class _DetailTicketScreenState extends State<DetailTicketScreen> {
); );
} }
Widget _buildDataBandara({
required String titleDeparture,
required String planeDeparture,
required String titleTransit,
required String planeTransit,
required String titleArrival,
required String planeArrival,
}) {
return Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
TypographyStyles.caption(titleDeparture, color: GrayColors.gray800),
TypographyStyles.caption(
planeDeparture,
color: GrayColors.gray600,
fontWeight: FontWeight.w400,
maxlines: 2,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 20.h),
if (titleTransit.isNotEmpty && planeTransit.isNotEmpty) ...[
TypographyStyles.caption(titleTransit, color: GrayColors.gray800),
TypographyStyles.caption(
planeTransit,
color: GrayColors.gray600,
fontWeight: FontWeight.w400,
maxlines: 2,
overflow: TextOverflow.ellipsis,
),
SizedBox(height: 20.h),
],
TypographyStyles.caption(titleArrival, color: GrayColors.gray800),
TypographyStyles.caption(
planeArrival,
color: GrayColors.gray600,
fontWeight: FontWeight.w400,
maxlines: 2,
overflow: TextOverflow.ellipsis,
)
],
),
);
}
void _showCetakBoardingPassBottomSheet(TransactionModel transaction) { void _showCetakBoardingPassBottomSheet(TransactionModel transaction) {
Get.bottomSheet( Get.bottomSheet(
backgroundColor: Colors.white, backgroundColor: Colors.white,

View File

@ -152,6 +152,18 @@ class _PrintBoardingPassScreenState extends State<PrintBoardingPassScreen> {
final passengerMap = (transaction.passengerDetails as List<dynamic>)[passenger] as Map<String, dynamic>; final passengerMap = (transaction.passengerDetails as List<dynamic>)[passenger] as Map<String, dynamic>;
final idBarcode = passengerMap['idBarcode'] ?? ''; final idBarcode = passengerMap['idBarcode'] ?? '';
final Map<String, dynamic>? svcMap = transaction.porterServiceDetails;
final services = <String>[];
if (svcMap?['departure'] != null) {
services.add(svcMap!['departure']['name'] as String);
}
if (svcMap?['transit'] != null) {
services.add(svcMap!['transit']['name'] as String);
}
if (svcMap?['arrival'] != null) {
services.add(svcMap!['arrival']['name'] as String);
}
return Padding( return Padding(
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.h), padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 20.h),
child: SingleChildScrollView( child: SingleChildScrollView(
@ -192,15 +204,15 @@ class _PrintBoardingPassScreenState extends State<PrintBoardingPassScreen> {
padding: EdgeInsets.symmetric(vertical: 10), padding: EdgeInsets.symmetric(vertical: 10),
child: Divider(thickness: 1, color: GrayColors.gray200), child: Divider(thickness: 1, color: GrayColors.gray200),
), ),
Row( Padding(
mainAxisAlignment: MainAxisAlignment.spaceBetween, padding: EdgeInsets.symmetric(vertical: 10.h),
children: [ child: layananClassGateSeat(
_buildColumnText(context, label: 'Layanan', value: 'value'), context: context,
_buildColumnText(context, services: services,
label: 'Class', value: transaction.flightDetails['flightClass']), flightClass: transaction.flightDetails['flightClass'],
_buildColumnText(context, label: 'Gate', value: 'value'), gate: 'Gate',
_buildColumnText(context, label: 'Seat', value: seatNumber), seatNumber: seatNumber,
], ),
), ),
Padding( Padding(
padding: EdgeInsets.symmetric(vertical: 20.h), padding: EdgeInsets.symmetric(vertical: 20.h),
@ -227,6 +239,53 @@ class _PrintBoardingPassScreenState extends State<PrintBoardingPassScreen> {
); );
} }
Widget layananClassGateSeat({
required BuildContext context,
required List<String> services,
required String flightClass,
required String gate,
required String seatNumber,
}) {
if (services.isEmpty) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildColumnText(context, label: 'Layanan', value: '-'),
_buildColumnText(context, label: 'Class', value: flightClass),
_buildColumnText(context, label: 'Gate', value: gate),
_buildColumnText(context, label: 'Seat', value: seatNumber),
],
);
}
if (services.length == 1) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildColumnText(context, label: 'Layanan', value: services.first),
_buildColumnText(context, label: 'Class', value: flightClass),
_buildColumnText(context, label: 'Gate', value: gate),
_buildColumnText(context, label: 'Seat', value: seatNumber),
],
);
}
final allServices = services.join(', ');
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildColumnText(context, label: 'Layanan', value: allServices),
SizedBox(height: 8.h),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_buildColumnText(context, label: 'Class', value: flightClass),
_buildColumnText(context, label: 'Gate', value: gate),
_buildColumnText(context, label: 'Seat', value: seatNumber),
],
),
],
);
}
Widget _buildColumnText( Widget _buildColumnText(
BuildContext context, { BuildContext context, {
required String label, required String label,

View File

@ -92,7 +92,7 @@ class CardFlightInformation extends StatelessWidget {
], ],
), ),
SizedBox(height: 4.h), SizedBox(height: 4.h),
Row( Wrap(
children: [ children: [
TypographyStyles.body(departureCity, color: GrayColors.gray800), TypographyStyles.body(departureCity, color: GrayColors.gray800),
SizedBox(width: 10.w), SizedBox(width: 10.w),

View File

@ -86,10 +86,19 @@ class _SearchTicketsScreenState extends State<SearchTicketsScreen> {
child: CircularProgressIndicator(), child: CircularProgressIndicator(),
); );
} else if (ticketController.ticketFlight.isEmpty) { } else if (ticketController.ticketFlight.isEmpty) {
final tanggal = DateFormat('EEE, d MMM yyyy').format(leavingDate);
final baseMsg = flightClass.isNotEmpty
? 'Maaf, tiket kelas $flightClass dari $from ke $to pada $tanggal tidak ditemukan.'
: 'Maaf, tiket dari $from ke $to pada $tanggal tidak ditemukan.';
return Center( return Center(
child: TypographyStyles.body( child: Padding(
"Tiket tidak ditemukan", padding: EdgeInsets.symmetric(horizontal: 24.w),
color: GrayColors.gray600, child: TypographyStyles.caption(
baseMsg,
color: GrayColors.gray400,
textAlign: TextAlign.center,
maxlines: 3,
),
), ),
); );
} else { } else {

View File

@ -59,7 +59,7 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
String? airLines; String? airLines;
String? code; String? code;
String? flightClass; String? flightClass;
String? transitAirplane; String? cityTransit;
String? stop; String? stop;
String? codeDeparture; String? codeDeparture;
String? codeArrival; String? codeArrival;
@ -141,7 +141,7 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
airLines = flight.airLines; airLines = flight.airLines;
code = flight.code; code = flight.code;
flightClass = flight.flightClass; flightClass = flight.flightClass;
transitAirplane = flight.transitAirplane; cityTransit = flight.cityTransit;
stop = flight.stop; stop = flight.stop;
codeDeparture = flight.codeDeparture; codeDeparture = flight.codeDeparture;
codeArrival = flight.codeArrival; codeArrival = flight.codeArrival;
@ -162,7 +162,7 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
plane: '${airLines} (${code})', plane: '${airLines} (${code})',
seatClass: '$flightClass', seatClass: '$flightClass',
passenger: '$passenger', passenger: '$passenger',
transiAirplane: '$transitAirplane', transiAirplane: '$cityTransit',
stop: '$stop', stop: '$stop',
airlineLogo: airlineLogo, airlineLogo: airlineLogo,
), ),
@ -188,7 +188,6 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
textColor: Colors.white, textColor: Colors.white,
backgroundColor: isAllPassengersFilled() ? PrimaryColors.primary800 : GrayColors.gray400, backgroundColor: isAllPassengersFilled() ? PrimaryColors.primary800 : GrayColors.gray400,
onTap: () { onTap: () {
// logger.d('Selected Passengers: $selectedPassengers');
if (selectedPassengers.any((p) => p == null)) { if (selectedPassengers.any((p) => p == null)) {
SnackbarHelper.showError('Error', 'Harap lengkapi slot penumpang'); SnackbarHelper.showError('Error', 'Harap lengkapi slot penumpang');
} else { } else {
@ -205,7 +204,7 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
'airLines': airLines, 'airLines': airLines,
'code': code, 'code': code,
'flightClass': flightClass, 'flightClass': flightClass,
'transitAirplane': transitAirplane, 'transitAirplane': cityTransit,
'stop': stop, 'stop': stop,
'codeDeparture': codeDeparture, 'codeDeparture': codeDeparture,
'codeArrival': codeArrival, 'codeArrival': codeArrival,
@ -232,7 +231,6 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
} else if (snapshot.hasData && snapshot.data != null) { } else if (snapshot.hasData && snapshot.data != null) {
final user = snapshot.data!; final user = snapshot.data!;
_loggedUser = user; _loggedUser = user;
// logger.d('Data user: ${user.noId}');
return CustomeShadowCotainner( return CustomeShadowCotainner(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -392,7 +390,6 @@ class _TicketBookingStep1ScreenState extends State<TicketBookingStep1Screen> {
shrinkWrap: true, shrinkWrap: true,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final passenger = profilController.passengerList[index]; final passenger = profilController.passengerList[index];
// logger.d("Passenger Models : ${passenger.noId}");
return Padding( return Padding(
padding: EdgeInsets.only(top: 16.h), padding: EdgeInsets.only(top: 16.h),
child: _buildAddPassenger( child: _buildAddPassenger(

View File

@ -1,5 +1,3 @@
import 'dart:developer';
import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart'; import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart';
import 'package:e_porter/_core/component/icons/icons_library.dart'; import 'package:e_porter/_core/component/icons/icons_library.dart';
import 'package:e_porter/_core/constants/colors.dart'; import 'package:e_porter/_core/constants/colors.dart';
@ -218,7 +216,7 @@ class _TicketBookingStep3ScreenState extends State<TicketBookingStep3Screen> {
seatClass: "${flightData?.flightClass}", seatClass: "${flightData?.flightClass}",
passenger: "$passenger", passenger: "$passenger",
stop: "${flightData?.stop}", stop: "${flightData?.stop}",
transiAirplane: "${flightData?.transitAirplane}", transiAirplane: "${flightData?.cityTransit}",
airlineLogo: "${flightData?.airlineLogo}", airlineLogo: "${flightData?.airlineLogo}",
), ),
SizedBox(height: 32.h), SizedBox(height: 32.h),
@ -309,13 +307,6 @@ class _TicketBookingStep3ScreenState extends State<TicketBookingStep3Screen> {
'selectedServiceLabels': selectedServiceLabels, 'selectedServiceLabels': selectedServiceLabels,
'selectedPorterServices': selectedPorterServices, 'selectedPorterServices': selectedPorterServices,
}; };
log('[Ticket Booking Step3] From ID: $fromId');
log('[Ticket Booking Step3] Ticket ID: $ticketId');
log('[Ticket Booking Step3] Flight ID: $flightId');
log('[Ticket Booking Step3] Ticket Date: $ticketDate');
log('[Ticket Booking Step3] Opsi Penerbangan: $selectedServiceLabels');
log('[Ticket Booking Step3] Layanan Porter: $selectedPorterServices');
Get.toNamed(Routes.TICKETBOOKINGSTEP4, arguments: argument); Get.toNamed(Routes.TICKETBOOKINGSTEP4, arguments: argument);
}, },
), ),

View File

@ -175,7 +175,7 @@ class _TicketBookingStep4ScreenState extends State<TicketBookingStep4Screen> {
plane: "${flightData?.airLines} (${flightData?.code})", plane: "${flightData?.airLines} (${flightData?.code})",
seatClass: "${flightData?.flightClass}", seatClass: "${flightData?.flightClass}",
passenger: "$passenger", passenger: "$passenger",
transiAirplane: "${flightData?.transitAirplane}", transiAirplane: "${flightData?.cityTransit}",
departurePorter: hasDeparturePorter ? "Keberangkatan (${getPorterInfo('departure')})" : null, departurePorter: hasDeparturePorter ? "Keberangkatan (${getPorterInfo('departure')})" : null,
arrivalPorter: hasArrivalPorter ? "Kedatangan (${getPorterInfo('arrival')})" : null, arrivalPorter: hasArrivalPorter ? "Kedatangan (${getPorterInfo('arrival')})" : null,
transitPorter: hasTransitPorter ? "Transit (${getPorterInfo('transit')})" : null, transitPorter: hasTransitPorter ? "Transit (${getPorterInfo('transit')})" : null,
@ -304,6 +304,10 @@ class _TicketBookingStep4ScreenState extends State<TicketBookingStep4Screen> {
'departureTime': flightData?.departureTime.millisecondsSinceEpoch, 'departureTime': flightData?.departureTime.millisecondsSinceEpoch,
'arrivalTime': flightData?.arrivalTime.millisecondsSinceEpoch, 'arrivalTime': flightData?.arrivalTime.millisecondsSinceEpoch,
'flightClass': flightData?.flightClass, 'flightClass': flightData?.flightClass,
'cityTransit': flightData?.cityTransit,
'codeTransit': flightData?.codeTransit,
'startDateTransit': flightData?.startDateTransit?.millisecondsSinceEpoch,
'endDateTransit': flightData?.endDateTransit?.millisecondsSinceEpoch,
'transitAirplane': flightData?.transitAirplane, 'transitAirplane': flightData?.transitAirplane,
'stop': flightData?.stop, 'stop': flightData?.stop,
'airlineLogo': flightData?.airlineLogo, 'airlineLogo': flightData?.airlineLogo,

View File

@ -4,6 +4,7 @@ import 'package:e_porter/_core/component/button/button_outline.dart';
import 'package:e_porter/_core/constants/colors.dart'; 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/permission_service.dart'; import 'package:e_porter/_core/service/permission_service.dart';
import 'package:e_porter/domain/bindings/navigation_binding.dart';
import 'package:e_porter/presentation/screens/navigation/main_navigation.dart'; import 'package:e_porter/presentation/screens/navigation/main_navigation.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -110,6 +111,7 @@ class _UploadFileScreenState extends State<UploadFileScreen> {
if (isHistoryMode) { if (isHistoryMode) {
Get.offAll( Get.offAll(
() => MainNavigation(initialTabIndex: 1), () => MainNavigation(initialTabIndex: 1),
binding: MainNavigationBinding(),
arguments: 'penumpang', arguments: 'penumpang',
); );
} else { } else {

View File

@ -441,7 +441,7 @@ packages:
source: hosted source: hosted
version: "3.0.1" version: "3.0.1"
logger: logger:
dependency: "direct main" dependency: "direct dev"
description: description:
name: logger name: logger
sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1 sha256: be4b23575aac7ebf01f225a241eb7f6b5641eeaf43c6a8613510fc2f8cf187d1

View File

@ -50,7 +50,6 @@ dependencies:
uuid: ^4.5.1 uuid: ^4.5.1
firebase_database: ^11.3.5 firebase_database: ^11.3.5
shared_preferences: ^2.4.6 shared_preferences: ^2.4.6
logger: ^2.5.0
dropdown_button2: ^2.3.9 dropdown_button2: ^2.3.9
google_fonts: ^6.2.1 google_fonts: ^6.2.1
dotted_dashed_line: ^0.0.3 dotted_dashed_line: ^0.0.3
@ -62,14 +61,15 @@ dependencies:
mobile_scanner: ^6.0.10 mobile_scanner: ^6.0.10
pdf: ^3.11.3 pdf: ^3.11.3
printing: ^5.14.2 printing: ^5.14.2
# workmanager: ^0.5.2
# workmanager: ^0.5.2
# pin_code_fields: ^8.0.1 # pin_code_fields: ^8.0.1
# dio: ^5.8.0+1 # dio: ^5.8.0+1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
logger: ^2.5.0
# The "flutter_lints" package below contains a set of recommended lints to # The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is # encourage good coding practices. The lint set provided by the package is