diff --git a/apps/edr-passenger-api/src/modules/segments/booking-flow-example.ts b/apps/edr-passenger-api/src/modules/segments/booking-flow-example.ts
deleted file mode 100644
index 7e912a6e2..000000000
--- a/apps/edr-passenger-api/src/modules/segments/booking-flow-example.ts
+++ /dev/null
@@ -1,238 +0,0 @@
-/**
- * SEGMENT-BASED SEAT RESERVATION EXAMPLE
- *
- * Demonstrates the complete flow for booking Addis Ababa → Dire Dawa
- * on the Addis Ababa → Djibouti route with segment-based seat management.
- *
- * Route: Addis Ababa (seq:1) → Adama (seq:2) → Awash (seq:3) → Dire Dawa (seq:4) → Aysha (seq:5) → Djibouti (seq:6)
- * Booking: Addis Ababa → Dire Dawa (segments: 1→2, 2→3, 3→4)
- */
-
-import { PrismaClient } from '@prisma/client';
-
-const prisma = new PrismaClient();
-
-async function exampleBookingFlow() {
- console.log('=== SEGMENT-BASED BOOKING FLOW ===\n');
-
- const scheduleId = 'schedule_add_dji_001';
- const passengerId = 'passenger_kelemu';
- const seatIds = ['seat_coach_a_1a', 'seat_coach_a_1b'];
- const originStationId = 'st_ADD';
- const destinationStationId = 'st_DRE';
-
- try {
- console.log('1. Checking seat availability...');
- const segments = await getJourneySegments(scheduleId, originStationId, destinationStationId);
- console.log('Journey segments:', segments.map(s => `${s.fromName} → ${s.toName}`));
-
- console.log('\n2. Holding seats...');
- const holdResult = await holdSeatsTransaction(scheduleId, seatIds, passengerId, originStationId, destinationStationId);
- console.log('Hold created:', holdResult);
-
- console.log('\n3. Processing payment...');
- await new Promise(resolve => setTimeout(resolve, 5000));
-
- console.log('\n4. Confirming booking...');
- const bookingId = 'booking_' + Date.now();
- const confirmResult = await confirmBookingTransaction(holdResult.holdId, bookingId, segments);
- console.log('Booking confirmed:', confirmResult);
-
- console.log('\n5. Simulating trip progress...');
- await simulateTripProgress(scheduleId, segments);
-
- } catch (error) {
- console.error('Booking flow error:', error);
- }
-}
-
-async function getJourneySegments(scheduleId: string, originStationId: string, destinationStationId: string) {
- const stopTimes = await prisma.tripStopTime.findMany({
- where: { scheduleId },
- include: { station: true },
- orderBy: { sequence: 'asc' },
- });
-
- const originStop = stopTimes.find(st => st.stationId === originStationId);
- const destinationStop = stopTimes.find(st => st.stationId === destinationStationId);
-
- if (!originStop || !destinationStop || originStop.sequence >= destinationStop.sequence) {
- throw new Error('Invalid origin/destination');
- }
-
- const segments = [];
- for (let i = originStop.sequence; i < destinationStop.sequence; i++) {
- const fromStop = stopTimes.find(st => st.sequence === i);
- const toStop = stopTimes.find(st => st.sequence === i + 1);
- if (fromStop && toStop) {
- segments.push({
- fromStationId: fromStop.stationId,
- toStationId: toStop.stationId,
- fromSequence: fromStop.sequence,
- toSequence: toStop.sequence,
- fromName: fromStop.station.name,
- toName: toStop.station.name,
- });
- }
- }
- return segments;
-}
-
-async function holdSeatsTransaction(scheduleId: string, seatIds: string[], passengerId: string, originStationId: string, destinationStationId: string) {
- return prisma.$transaction(async (tx) => {
- console.log(' → Starting seat hold transaction...');
-
- const seats = await tx.seat.findMany({ where: { id: { in: seatIds } }, include: { coach: true } });
- if (seats.length !== seatIds.length) throw new Error('Some seats not found');
-
- for (const seat of seats) {
- if (seat.status !== 'AVAILABLE') {
- throw new Error(`Seat ${seat.seatNumber} is not available (status: ${seat.status})`);
- }
- }
-
- const expiresAt = new Date(Date.now() + 10 * 60 * 1000);
- const seatHold = await tx.seatHold.create({
- data: { scheduleId, seatIds, passengerId, expiresAt },
- });
-
- await tx.seat.updateMany({ where: { id: { in: seatIds } }, data: { status: 'HELD', heldUntil: expiresAt } });
-
- console.log(' → Seats held successfully');
- return { holdId: seatHold.id, expiresAt, seats: seatIds.length };
- });
-}
-
-async function confirmBookingTransaction(holdId: string, bookingId: string, segments: any[]) {
- return prisma.$transaction(async (tx) => {
- console.log(' → Starting booking confirmation transaction...');
-
- const hold = await tx.seatHold.findUnique({ where: { id: holdId } });
- if (!hold || hold.expiresAt < new Date()) throw new Error('Hold expired or not found');
-
- const booking = await tx.booking.create({
- data: {
- id: bookingId,
- bookingRef: 'BK' + Date.now().toString().slice(-6),
- passengerId: hold.passengerId,
- scheduleId: hold.scheduleId,
- status: 'CONFIRMED',
- totalMinor: 45000,
- currency: 'ETB',
- },
- });
-
- const journey = await tx.journey.create({
- data: { passengerId: hold.passengerId, status: 'CONFIRMED', totalMinor: 45000, currency: 'ETB' },
- });
-
- for (const seatId of hold.seatIds) {
- for (let i = 0; i < segments.length; i++) {
- await tx.journeySegment.create({
- data: {
- journeyId: journey.id,
- scheduleId: hold.scheduleId,
- segmentOrder: i + 1,
- seatId,
- departureStationId: segments[i].fromStationId,
- arrivalStationId: segments[i].toStationId,
- },
- });
- }
- }
-
- for (const seatId of hold.seatIds) {
- await tx.bookingSeat.create({ data: { bookingId, seatId, passengerName: 'Kelemu Ketsela' } });
- }
-
- await tx.seat.updateMany({ where: { id: { in: hold.seatIds } }, data: { status: 'BOOKED', heldUntil: null } });
- await tx.seatHold.delete({ where: { id: holdId } });
-
- console.log(' → Booking confirmed successfully');
- return { bookingId, bookingRef: booking.bookingRef, confirmedSeats: hold.seatIds.length, segments: segments.length };
- });
-}
-
-async function simulateTripProgress(scheduleId: string, bookedSegments: any[]) {
- console.log(' → Simulating trip progress...');
-
- for (const segment of bookedSegments) {
- console.log(` → Train approaching ${segment.toName}...`);
-
- await prisma.tripLiveStatus.upsert({
- where: { scheduleId },
- update: { currentLocationLabel: segment.toName, progressPercent: Math.round((segment.toSequence / 4) * 100) },
- create: {
- scheduleId,
- state: 'EN_ROUTE',
- currentLocationLabel: segment.toName,
- progressPercent: Math.round((segment.toSequence / 4) * 100),
- delayMinutes: 0,
- },
- });
-
- if (segment.toName === 'Dire Dawa') {
- console.log(' → Passengers reached destination, releasing seats...');
- await releaseSeatsAtStation(scheduleId, segment.toStationId);
- }
-
- await new Promise(resolve => setTimeout(resolve, 2000));
- }
-}
-
-async function releaseSeatsAtStation(scheduleId: string, stationId: string) {
- return prisma.$transaction(async (tx) => {
- const completedSegments = await tx.journeySegment.findMany({
- where: { scheduleId, arrivalStationId: stationId },
- include: { journey: { include: { journeySegments: { where: { scheduleId } } } } },
- });
-
- const seatsToRelease: string[] = [];
-
- for (const segment of completedSegments) {
- const passengerSegments = segment.journey.journeySegments.filter((js: any) => js.seatId === segment.seatId);
- const maxOrder = Math.max(...passengerSegments.map((js: any) => js.segmentOrder));
- if (segment.segmentOrder === maxOrder) seatsToRelease.push(segment.seatId!);
- }
-
- if (seatsToRelease.length > 0) {
- await tx.seat.updateMany({ where: { id: { in: seatsToRelease } }, data: { status: 'AVAILABLE' } });
- console.log(` → Released ${seatsToRelease.length} seats at station`);
- }
-
- return seatsToRelease;
- });
-}
-
-async function checkOverlappingReservations(tx: any, scheduleId: string, seatId: string, segments: any[]) {
- const activeHolds = await tx.seatHold.findMany({
- where: { scheduleId, seatIds: { has: seatId }, expiresAt: { gt: new Date() } },
- });
-
- const activeBookings = await tx.journeySegment.findMany({
- where: {
- scheduleId,
- seatId,
- journey: { status: { in: ['PENDING_PAYMENT', 'CONFIRMED'] } },
- },
- });
-
- return [...activeHolds, ...activeBookings];
-}
-
-if (require.main === module) {
- exampleBookingFlow()
- .then(() => console.log('\n=== EXAMPLES COMPLETED ==='))
- .catch(console.error)
- .finally(() => prisma.$disconnect());
-}
-
-export {
- exampleBookingFlow,
- getJourneySegments,
- holdSeatsTransaction,
- confirmBookingTransaction,
- simulateTripProgress,
- releaseSeatsAtStation,
- checkOverlappingReservations,
-};
diff --git a/apps/edr-passenger-web/backoffice/src/app/app-releases/page.tsx b/apps/edr-passenger-web/backoffice/src/app/app-releases/page.tsx
index 2e036f31e..c5d5d7fa9 100644
--- a/apps/edr-passenger-web/backoffice/src/app/app-releases/page.tsx
+++ b/apps/edr-passenger-web/backoffice/src/app/app-releases/page.tsx
@@ -165,7 +165,7 @@ export default function AppReleasesPage() {
-
{t.ticketNumber}
diff --git a/apps/edr-passenger-web/backoffice/test-routes.html b/apps/edr-passenger-web/backoffice/test-routes.html
deleted file mode 100644
index e34849a03..000000000
--- a/apps/edr-passenger-web/backoffice/test-routes.html
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
Test Routes API
-
-
-
-
Routes API Test
-
-
-
-
-
-
-
-
-
diff --git a/apps/edr-passenger-web/backoffice/test-stations-crud.js b/apps/edr-passenger-web/backoffice/test-stations-crud.js
deleted file mode 100644
index 7964cc813..000000000
--- a/apps/edr-passenger-web/backoffice/test-stations-crud.js
+++ /dev/null
@@ -1,132 +0,0 @@
-// Test script for Stations CRUD operations
-// Run this in the browser console on the backoffice app
-
-async function testStationsCRUD() {
- const API_URL = 'http://localhost:4000';
- const token = localStorage.getItem('auth_token');
-
- const headers = {
- 'Content-Type': 'application/json',
- 'Authorization': token ? `Bearer ${token}` : ''
- };
-
- console.log('🧪 Testing Stations CRUD Operations...\n');
-
- try {
- // 1. CREATE - Add a new station
- console.log('1️⃣ Testing CREATE Station...');
- const newStation = {
- code: 'TEST',
- name: 'Test Station',
- city: 'Test City',
- countryCode: 'ET',
- lat: '9.0320',
- lng: '38.7469',
- timezone: 'Africa/Addis_Ababa',
- isOperational: true
- };
-
- const createResponse = await fetch(`${API_URL}/stations`, {
- method: 'POST',
- headers,
- body: JSON.stringify(newStation)
- });
-
- if (!createResponse.ok) {
- throw new Error(`CREATE failed: ${createResponse.status} ${await createResponse.text()}`);
- }
-
- const createdStation = await createResponse.json();
- console.log('✅ Station created:', createdStation);
- const stationId = createdStation.id || createdStation.data?.id;
-
- if (!stationId) {
- throw new Error('No station ID returned from create');
- }
-
- // 2. READ - Get the created station
- console.log('\n2️⃣ Testing READ Station...');
- const readResponse = await fetch(`${API_URL}/stations/${stationId}`, {
- method: 'GET',
- headers
- });
-
- if (!readResponse.ok) {
- throw new Error(`READ failed: ${readResponse.status}`);
- }
-
- const readStation = await readResponse.json();
- console.log('✅ Station retrieved:', readStation);
-
- // 3. UPDATE - Modify the station
- console.log('\n3️⃣ Testing UPDATE Station...');
- const updateData = {
- name: 'Test Station Updated',
- city: 'Test City Updated',
- isOperational: false
- };
-
- const updateResponse = await fetch(`${API_URL}/stations/${stationId}`, {
- method: 'PATCH',
- headers,
- body: JSON.stringify(updateData)
- });
-
- if (!updateResponse.ok) {
- throw new Error(`UPDATE failed: ${updateResponse.status} ${await updateResponse.text()}`);
- }
-
- const updatedStation = await updateResponse.json();
- console.log('✅ Station updated:', updatedStation);
-
- // 4. LIST - Get all stations
- console.log('\n4️⃣ Testing LIST Stations...');
- const listResponse = await fetch(`${API_URL}/stations`, {
- method: 'GET',
- headers
- });
-
- if (!listResponse.ok) {
- throw new Error(`LIST failed: ${listResponse.status}`);
- }
-
- const stations = await listResponse.json();
- console.log('✅ Stations list retrieved:', stations);
-
- // 5. DELETE - Remove the test station
- console.log('\n5️⃣ Testing DELETE Station...');
- const deleteResponse = await fetch(`${API_URL}/stations/${stationId}`, {
- method: 'DELETE',
- headers
- });
-
- if (!deleteResponse.ok) {
- throw new Error(`DELETE failed: ${deleteResponse.status} ${await deleteResponse.text()}`);
- }
-
- console.log('✅ Station deleted successfully');
-
- // 6. Verify deletion
- console.log('\n6️⃣ Verifying deletion...');
- const verifyResponse = await fetch(`${API_URL}/stations/${stationId}`, {
- method: 'GET',
- headers
- });
-
- if (verifyResponse.status === 404) {
- console.log('✅ Station deletion verified (404 Not Found)');
- } else {
- console.warn('⚠️ Station might still exist');
- }
-
- console.log('\n🎉 All tests passed!');
- return { success: true, message: 'All CRUD operations working correctly' };
-
- } catch (error) {
- console.error('❌ Test failed:', error);
- return { success: false, error: error.message };
- }
-}
-
-// Run the test
-testStationsCRUD();
diff --git a/apps/edr-passenger-web/portal/src/app/booking/confirmation/page.tsx b/apps/edr-passenger-web/portal/src/app/booking/confirmation/page.tsx
index fca170a2c..c56ccd304 100644
--- a/apps/edr-passenger-web/portal/src/app/booking/confirmation/page.tsx
+++ b/apps/edr-passenger-web/portal/src/app/booking/confirmation/page.tsx
@@ -37,7 +37,6 @@ export default function ConfirmationPage() {
try {
return await apiClient.get(`/bookings/${bookingId}`);
} catch (error) {
- console.log('Booking API not available, using local data');
return {
id: bookingId || '',
pnr: pnr || undefined,
@@ -57,13 +56,9 @@ export default function ConfirmationPage() {
// For other payment methods, ticket is generated by the payment webhook after payment completes
apiClient.get(`/bookings/${bookingId}`).then((data: any) => {
if (data?.status === 'CONFIRMED') {
- apiClient.post(`/tickets/generate/${bookingId}`).catch((err) => {
- console.error('Failed to generate ticket:', err);
- });
+ apiClient.post(`/tickets/generate/${bookingId}`).catch(() => {});
}
- }).catch((err) => {
- console.error('Failed to fetch booking status:', err);
- });
+ }).catch(() => {});
}
}, [bookingId]);
@@ -142,7 +137,6 @@ export default function ConfirmationPage() {
if (i < passengers.length - 1) await new Promise(r => setTimeout(r, 400));
}
} catch (error) {
- console.error('❌ Failed to generate voucher:', error);
alert(`Failed to generate voucher: ${error instanceof Error ? error.message : 'Unknown error'}`);
} finally {
setIsGeneratingVoucher(false);
diff --git a/apps/edr-passenger-web/portal/src/app/booking/detail/page.tsx b/apps/edr-passenger-web/portal/src/app/booking/detail/page.tsx
index f01ab89c6..5087b7e4d 100644
--- a/apps/edr-passenger-web/portal/src/app/booking/detail/page.tsx
+++ b/apps/edr-passenger-web/portal/src/app/booking/detail/page.tsx
@@ -34,9 +34,7 @@ function BookingDetailContent() {
queryKey: ['booking-detail', bookingRef],
queryFn: async () => {
if (!bookingRef) throw new Error('No booking reference provided');
- console.log('🔍 Fetching Booking:', bookingRef);
const response = await apiClient.get(`/bookings/${bookingRef}`);
- console.log('✅ Booking Response:', response);
// Handle wrapped response
return (response as any)?.data || response;
},
@@ -56,7 +54,6 @@ function BookingDetailContent() {
return response;
},
onSuccess: async (data: any) => {
- console.log('Payment intent created:', data);
await apiClient.patch(`/bookings/${booking?.id}/confirm`, {
paymentIntentId: data.id,
paymentMethod: selectedPaymentMethod,
@@ -64,7 +61,6 @@ function BookingDetailContent() {
refetch();
},
onError: (error: any) => {
- console.error('Payment failed:', error);
alert(error?.response?.data?.message || 'Payment failed. Please try again.');
},
});
@@ -99,11 +95,9 @@ function BookingDetailContent() {
setIsGeneratingVoucher(true);
try {
- console.log('📄 Generating voucher for booking:', booking);
const { generateVoucherPDF } = await import('@/lib/generate-voucher');
await generateVoucherPDF(booking as any);
} catch (error) {
- console.error('Failed to generate voucher:', error);
alert(`Failed to generate voucher: ${error instanceof Error ? error.message : 'Unknown error'}`);
} finally {
setIsGeneratingVoucher(false);
@@ -148,11 +142,6 @@ function BookingDetailContent() {
const isExpired = booking.status === 'EXPIRED';
const isCancelled = booking.status === 'CANCELLED';
- console.log('📊 Booking Status:', booking.status);
- console.log('📊 isPendingPayment:', isPendingPayment);
- console.log('📊 isConfirmed:', isConfirmed);
- console.log('📊 isExpired:', isExpired);
- console.log('📊 isCancelled:', isCancelled);
const StatusBadge = () => {
const statusConfig = {
diff --git a/apps/edr-passenger-web/portal/src/app/booking/passengers/page.tsx b/apps/edr-passenger-web/portal/src/app/booking/passengers/page.tsx
index d5857ac98..4263108d1 100644
--- a/apps/edr-passenger-web/portal/src/app/booking/passengers/page.tsx
+++ b/apps/edr-passenger-web/portal/src/app/booking/passengers/page.tsx
@@ -736,7 +736,6 @@ export default function PassengersPage() {
// Remove code/state from the URL so a refresh doesn't re-trigger
router.replace('/booking/passengers');
} catch (error) {
- console.error('Failed to complete Fayda verification:', error);
setVerificationStatus((prev) => ({ ...prev, [targetIndex]: 'error' }));
setFaydaErrors((prev) => ({ ...prev, [targetIndex]: 'Fayda verification failed. Please try again or enter details manually.' }));
} finally {
@@ -768,7 +767,6 @@ export default function PassengersPage() {
try {
// Fetch passenger profile from backend
const passengerData: any = await apiClient.get(`/passengers/me`);
- console.log('Fetched passenger data:', passengerData);
if (!passengerData) {
setFormInitialized(true);
@@ -776,7 +774,6 @@ export default function PassengersPage() {
}
// Only populate first passenger
- console.log('Setting passenger 0 values');
setValue('passengers.0.name', passengerData?.fullName || user.fullName || '');
setValue('passengers.0.dateOfBirth', passengerData?.dateOfBirth || user.dateOfBirth || '');
if (passengerData?.gender || user.gender) setValue('passengers.0.gender', (passengerData?.gender || user.gender) as any);
@@ -793,7 +790,6 @@ export default function PassengersPage() {
setFormInitialized(true);
} catch (error) {
- console.error('Failed to fetch passenger data:', error);
setFormInitialized(true);
}
};
@@ -879,7 +875,6 @@ export default function PassengersPage() {
setFaydaErrors((prev) => ({ ...prev, [index]: 'Fayda verification was not completed. Please try again or enter details manually.' }));
}
} catch (error) {
- console.error('Failed to get verification status:', error);
setVerificationStatus((prev) => ({ ...prev, [index]: 'error' }));
setFaydaErrors((prev) => ({ ...prev, [index]: 'Failed to confirm verification status. Please try again or enter details manually.' }));
} finally {
@@ -889,7 +884,6 @@ export default function PassengersPage() {
}
}, 1000);
} catch (error) {
- console.error('Failed to start Fayda verification:', error);
setVerificationStatus((prev) => ({ ...prev, [index]: 'error' }));
setFaydaErrors((prev) => ({ ...prev, [index]: 'Failed to start verification. Please try again.' }));
setVerifyingIndex(null);
@@ -918,9 +912,7 @@ export default function PassengersPage() {
try {
const passengerProfile: any = await apiClient.get('/passengers/me');
passengerId = passengerProfile?.id || '';
- console.log('Fetched passengerId:', passengerId);
} catch (error) {
- console.error('Failed to fetch passenger profile:', error);
}
}
@@ -958,12 +950,10 @@ export default function PassengersPage() {
if (isAuthenticated && passengerId) {
const { setPassengerId } = useBookingStore.getState();
setPassengerId(passengerId);
- console.log('Saved passengerId to booking store:', passengerId);
}
router.push('/booking/seats');
} catch (error) {
- console.error('Failed to save passenger details:', error);
alert('Failed to save passenger details. Please try again.');
} finally {
setSaving(false);
diff --git a/apps/edr-passenger-web/portal/src/app/booking/payment/page.tsx b/apps/edr-passenger-web/portal/src/app/booking/payment/page.tsx
index ecba48945..5413af78c 100644
--- a/apps/edr-passenger-web/portal/src/app/booking/payment/page.tsx
+++ b/apps/edr-passenger-web/portal/src/app/booking/payment/page.tsx
@@ -59,9 +59,7 @@ export default function PaymentPage() {
queryKey: ['bookingAmount', bookingId, amountCurrency, selectedMethod],
queryFn: async () => {
const url = `/payments/booking-amount?bookingId=${bookingId}¤cy=${amountCurrency}`;
- console.log('[BookingAmount] Request:', { url, bookingId, currency: amountCurrency, selectedMethod });
const response: any = await apiClient.get(url);
- console.log('[BookingAmount] Response:', response);
return response;
},
enabled: !!selectedMethod && !!bookingId,
@@ -115,7 +113,6 @@ export default function PaymentPage() {
router.push("/booking/confirmation");
},
onError: (error: any) => {
- console.error("Payment failed:", error);
updateStatus("FAILED");
setPaymentError(
error?.response?.data?.message ||
@@ -160,10 +157,6 @@ export default function PaymentPage() {
// Add a small delay to allow state to be set from previous page
const timer = setTimeout(() => {
if (!bookingId || !pnr) {
- console.log(
- "Payment page: Missing booking data, redirecting to search",
- );
- console.log("bookingId:", bookingId, "pnr:", pnr);
router.push("/booking/search");
}
}, 500);
diff --git a/apps/edr-passenger-web/portal/src/app/booking/results/page.tsx b/apps/edr-passenger-web/portal/src/app/booking/results/page.tsx
index 70ada8f7c..6a54fe010 100644
--- a/apps/edr-passenger-web/portal/src/app/booking/results/page.tsx
+++ b/apps/edr-passenger-web/portal/src/app/booking/results/page.tsx
@@ -107,11 +107,9 @@ export default function ResultsPage() {
payload.returnDate = searchData.returnDate;
}
- console.log('🚂 Search Request:', JSON.stringify(payload, null, 2));
const response = await apiClient.post('/search', payload) as any;
- console.log('✅ Search Response:', JSON.stringify(response, null, 2));
return response;
},
diff --git a/apps/edr-passenger-web/portal/src/app/booking/review/page.tsx b/apps/edr-passenger-web/portal/src/app/booking/review/page.tsx
index 241e6fea9..4dcf82bd9 100644
--- a/apps/edr-passenger-web/portal/src/app/booking/review/page.tsx
+++ b/apps/edr-passenger-web/portal/src/app/booking/review/page.tsx
@@ -15,13 +15,11 @@ import { isChild, isFirstChild, formatFare } from '@/utils/fare-utils';
function getPassengerIdFromToken(token: string): string | null {
try {
if (!token) {
- console.warn('No token provided');
return null;
}
const parts = token.split('.');
if (parts.length !== 3) {
- console.warn('Invalid token format - expected 3 parts, got', parts.length);
return null;
}
@@ -33,21 +31,16 @@ function getPassengerIdFromToken(token: string): string | null {
try {
decoded = JSON.parse(atob(padded));
} catch (e) {
- console.error('Failed to parse base64:', e);
return null;
}
- console.log('Decoded JWT payload keys:', Object.keys(decoded));
- console.log('passengerId from JWT:', decoded.passengerId);
if (!decoded.passengerId) {
- console.warn('No passengerId in JWT payload, available keys:', Object.keys(decoded));
return null;
}
return decoded.passengerId;
} catch (error) {
- console.error('Error in getPassengerIdFromToken:', error);
return null;
}
}
@@ -149,7 +142,6 @@ export default function ReviewPage() {
setSeatDetails(details);
} catch (error) {
- console.error('Failed to fetch seat details:', error);
}
};
@@ -159,9 +151,6 @@ export default function ReviewPage() {
const createBookingMutation = useMutation({
mutationFn: (data: any) => {
const endpoint = isAuthenticated ? '/bookings' : '/bookings/guest';
- console.log('=== API REQUEST ===');
- console.log('Endpoint:', endpoint);
- console.log('Request Data:', JSON.stringify(data, null, 2));
return apiClient.post(endpoint, data);
},
onSuccess: (data: any) => {
@@ -201,7 +190,6 @@ export default function ReviewPage() {
}
if (!searchCriteria?.originStationId || !searchCriteria?.destinationStationId) {
- console.error('Missing search criteria');
alert('Missing search criteria. Please start over.');
router.push('/booking/search');
return;
@@ -225,10 +213,8 @@ export default function ReviewPage() {
seatClassId = outboundClassName ? findByName(outboundClassName) : seatClasses[0].id;
returnSeatClassId = returnClassName ? findByName(returnClassName) : seatClasses[0].id;
- console.log('Seat class lookup:', { outboundClassName, returnClassName, seatClassId, returnSeatClassId });
}
} catch (err) {
- console.error('Failed to fetch seat classes:', err);
}
if (!seatClassId) {
@@ -242,11 +228,9 @@ export default function ReviewPage() {
const token = typeof window !== 'undefined' ? localStorage.getItem('auth_token') : null;
if (!token) {
- console.error('No token in localStorage');
throw new Error('Authentication token not found. Please log in again.');
}
- console.log('Token found, length:', token.length);
let passengerId = getPassengerIdFromToken(token);
@@ -274,7 +258,6 @@ export default function ReviewPage() {
const me: any = await apiClient.get('/passengers/me');
passengerId = me?.id || me?.passengerId || '';
} catch (err) {
- console.error('Failed to resolve passengerId from /passengers/me:', err);
}
}
@@ -379,11 +362,8 @@ export default function ReviewPage() {
localStorage.setItem('deviceId', bookingData.deviceId);
}
- console.log('Creating booking with payload:', JSON.stringify(bookingData, null, 2));
- console.log('API endpoint:', isAuthenticated ? '/bookings' : '/bookings/guest');
await createBookingMutation.mutateAsync(bookingData);
} catch (error) {
- console.error('Error in handleConfirm:', error);
alert(error instanceof Error ? error.message : 'An unexpected error occurred. Please try again.');
}
};
@@ -392,29 +372,18 @@ export default function ReviewPage() {
if (isRoundTrip) {
if (!outboundSchedule || !inboundSchedule || !passengers.length) {
if (!createBookingMutation.isPending && !createBookingMutation.isSuccess) {
- console.log('Redirecting to search - missing round trip data');
router.push('/booking/search');
}
}
} else {
if (!selectedSchedule || !passengers.length) {
if (!createBookingMutation.isPending && !createBookingMutation.isSuccess) {
- console.log('Redirecting to search - missing data');
router.push('/booking/search');
}
}
}
}, [isRoundTrip, selectedSchedule, outboundSchedule, inboundSchedule, passengers.length, createBookingMutation.isPending, createBookingMutation.isSuccess, router]);
- if (isRoundTrip && (!outboundSchedule || !inboundSchedule || !passengers.length)) {
- return null;
- }
-
- if (!isRoundTrip && (!selectedSchedule || !passengers.length)) {
- return null;
- }
-
-
const fetchFareBreakdown = useCallback(async (scheduleId: string, originStationId: string, destinationStationId: string) => {
try {
const seatClasses: any[] = await apiClient.get('/seat-classes');
@@ -445,7 +414,6 @@ export default function ReviewPage() {
const result: any = await apiClient.get(`/search/fare-breakdown?${params}`);
setFareBreakdown(result);
} catch (err) {
- console.error('Failed to fetch fare breakdown:', err);
}
}, [passengers, selectedSchedule, outboundSchedule, isRoundTrip, searchCriteria, displayCurrency]);
@@ -456,6 +424,14 @@ export default function ReviewPage() {
fetchFareBreakdown(scheduleId, searchCriteria.originStationId, searchCriteria.destinationStationId);
}, [fetchFareBreakdown, isRoundTrip, outboundSchedule?.id, selectedSchedule?.id, searchCriteria?.originStationId, searchCriteria?.destinationStationId]);
+ if (isRoundTrip && (!outboundSchedule || !inboundSchedule || !passengers.length)) {
+ return null;
+ }
+
+ if (!isRoundTrip && (!selectedSchedule || !passengers.length)) {
+ return null;
+ }
+
const total = packageTierPriceMinor ?? fareBreakdown?.totalMinor ?? 0;
// Shared fare sidebar — rendered in right column (desktop) and inline (mobile)
diff --git a/apps/edr-passenger-web/portal/src/app/booking/seats/page.tsx b/apps/edr-passenger-web/portal/src/app/booking/seats/page.tsx
index 5c717bd39..537e20623 100644
--- a/apps/edr-passenger-web/portal/src/app/booking/seats/page.tsx
+++ b/apps/edr-passenger-web/portal/src/app/booking/seats/page.tsx
@@ -173,21 +173,11 @@ export default function SeatsPage() {
queryKey: ["seatmap", currentSchedule?.id, coachTypeId, currentJourneyType],
queryFn: async () => {
const endpoint = `/seats/seatmap/${currentSchedule?.id}?coachTypeId=${coachTypeId}&journeyDirection=${journeyDirection}`;
- console.log("🪑 Seatmap Request:", {
- endpoint,
- });
const response = await apiClient.get(endpoint);
- console.log("✅ Seatmap Response:", {
- endpoint,
- fullResponse: response,
- dataCoaches: (response as any)?.data?.coaches?.length || 0,
- rootCoaches: (response as any)?.coaches?.length || 0,
- });
const finalData = (response as any)?.data || response;
- console.log("🎯 Final data structure:", finalData);
return finalData;
},
enabled: !!currentSchedule?.id && !!coachTypeId,
@@ -210,7 +200,6 @@ export default function SeatsPage() {
const originId = (scheduleForHold as any)?.originStationId || searchCriteria?.originStationId;
const destinationId = (scheduleForHold as any)?.destinationStationId || searchCriteria?.destinationStationId;
- console.log('🎫 Hold request:', { scheduleId: currentSchedule?.id, originId, destinationId, isInbound });
return apiClient.post(`/seats/hold`, {
scheduleId: currentSchedule?.id,
originStationId: originId,
@@ -258,29 +247,10 @@ export default function SeatsPage() {
(seatMapData as any)?.coaches ||
(seatMapData as any)?.data?.coaches ||
[];
- console.log("📦 Raw coaches data:", {
- fromRoot: (seatMapData as any)?.coaches?.length || 0,
- fromData: (seatMapData as any)?.data?.coaches?.length || 0,
- using: rawCoaches.length,
- hasRooms: rawCoaches.some((c: any) => c.rooms?.length > 0),
- sampleRooms: rawCoaches[0]?.rooms?.length || 0,
- });
return rawCoaches;
}, [seatMapData]);
const filteredCoaches = useMemo(() => {
- console.log("🔍 Filtering coaches:", {
- totalCoaches: coaches.length,
- selectedSeatClass: currentSchedule?.selectedSeatClass,
- coachesData: coaches.map((c: any) => ({
- id: c.id,
- name: c.name,
- label: c.label,
- seatClass: c.seatClass,
- seatClasses: c.seatClasses,
- seatsCount: c.seats?.length || 0,
- })),
- });
const coachesWithSeats = coaches.filter((c: any) => {
// Bed coaches store occupants in rooms.beds, not seats
@@ -288,12 +258,8 @@ export default function SeatsPage() {
return c.seats && c.seats.length > 0;
});
- console.log(
- "✅ Returning all coaches with seats/beds:",
- coachesWithSeats.length,
- );
return coachesWithSeats;
- }, [coaches, currentSchedule?.selectedSeatClass]);
+ }, [coaches]);
const selectedCoachData = useMemo(
diff --git a/apps/edr-passenger-web/portal/src/types/index.ts b/apps/edr-passenger-web/portal/src/types/index.ts
index 1e073dcc0..d1a906cbb 100644
--- a/apps/edr-passenger-web/portal/src/types/index.ts
+++ b/apps/edr-passenger-web/portal/src/types/index.ts
@@ -28,6 +28,8 @@ export interface Schedule {
};
originStation?: Station; // For backward compatibility
destinationStation?: Station; // For backward compatibility
+ originStationId?: string; // For backward compatibility
+ destinationStationId?: string; // For backward compatibility
departureAt?: string; // API returns this
arrivalAt?: string; // API returns this
departureTime?: string; // For backward compatibility