/** * YATRA DEPARTURE MANAGEMENT * Comprehensive departure view for travel booking businesses * Complete operational insights for tour operators */ import React, { useState } from "react"; import { useQuery } from "@tanstack/react-query"; import { __ } from "../lib/i18n"; import { formatDate as formatDateUtil } from "../lib/dateFormat"; import { apiClient } from "../lib/api-client"; import { Card, CardContent, CardHeader, CardTitle, CardDescription, } from "../components/ui/card"; // Button available for future use // import { Button } from '../components/ui/button'; import { Badge } from "../components/ui/badge"; // Skeleton Loading Components const SkeletonMetricCard = () => (
); // SkeletonTabContent available for future use - exported to suppress unused warning export const SkeletonTabContent = () => (
{[...Array(4)].map((_, i) => (
))}
{[...Array(3)].map((_, i) => (
))}
); // SVG Icons for ViewDeparture const SVGIcons = { Truck: () => ( ), Calendar: () => ( ), Users: () => ( ), DollarSign: () => ( ), Activity: () => ( ), BarChart: () => ( ), MapPin: () => ( ), FileText: () => ( ), Info: () => ( ), XCircle: () => ( ), }; const ViewDeparture: React.FC = () => { const [activeTab, setActiveTab] = useState("overview"); // Get departure ID from URL const params = new URLSearchParams(window.location.search); const idParam = params.get("id"); const tripIdParam = params.get("trip_id"); const id = idParam ? parseInt(idParam, 10) : NaN; const tripId = tripIdParam ? parseInt(tripIdParam, 10) : NaN; // Fetch departure data using apiClient const { data: departureData, isLoading, error, } = useQuery({ queryKey: ["departure-details", tripId, id], enabled: Number.isFinite(id) && Number.isFinite(tripId), queryFn: async () => { if (!Number.isFinite(id) || !Number.isFinite(tripId)) { throw new Error(__("Invalid departure or trip ID", "yatra")); } const response = await apiClient.get(`/trips/${tripId}/departures/${id}`); const payload = response?.data ?? response; return payload && typeof payload === "object" ? payload : {}; }, }); const formatCurrency = (amount: number) => { return new Intl.NumberFormat("en-US", { style: "currency", currency: "USD", }).format(amount); }; const formatDate = (dateString: string) => { return formatDateUtil(dateString); }; const formatTime = (timeString: string) => { return new Date(`2000-01-01T${timeString}`).toLocaleTimeString("en-US", { hour: "numeric", minute: "2-digit", hour12: true, }); }; if (!Number.isFinite(id) || !Number.isFinite(tripId)) { return (

{__("Departure Not Found", "yatra")}

{__( "Missing or invalid departure ID or trip ID in the URL.", "yatra", )}

); } if (isLoading) { return (
); } if (error) { return (

{__("Error Loading Departure", "yatra")}

{(error as any)?.message || __("Unable to load departure details.", "yatra")}

); } const departure = departureData || {}; const trip = departure.trip || {}; // Calculate metrics const maxCapacity = departure.max_capacity || 0; const bookedCount = departure.booked_count || 0; const availableSpots = maxCapacity - bookedCount; const occupancyRate = maxCapacity > 0 ? (bookedCount / maxCapacity) * 100 : 0; // Status styling const getStatusStyle = (status: string) => { switch (status) { case "confirmed": return "bg-green-100 dark:bg-green-900/20 text-green-800 dark:text-green-400 border-green-200 dark:border-green-800"; case "upcoming": return "bg-blue-100 dark:bg-blue-900/20 text-blue-800 dark:text-blue-400 border-blue-200 dark:border-blue-800"; case "full": return "bg-orange-100 dark:bg-orange-900/20 text-orange-800 dark:text-orange-400 border-orange-200 dark:border-orange-800"; case "past": return "bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-300 border-gray-200 dark:border-gray-700"; case "cancelled": return "bg-red-100 dark:bg-red-900/20 text-red-800 dark:text-red-400 border-red-200 dark:border-red-800"; default: return "bg-gray-100 dark:bg-gray-800 text-gray-800 dark:text-gray-300 border-gray-200 dark:border-gray-700"; } }; const tabs = [ { id: "overview", label: "Overview", icon: "BarChart" }, { id: "bookings", label: "Bookings", icon: "Calendar" }, { id: "travelers", label: "Travelers", icon: "Users" }, { id: "financials", label: "Financials", icon: "DollarSign" }, { id: "operations", label: "Operations", icon: "Activity" }, ]; return (
{/* Header */}
{trip.title || __("Departure Details", "yatra")} {departure.start_date && formatDate(departure.start_date)} {departure.time && ` ${__("at", "yatra")} ${formatTime(departure.time)}`}
{departure.status || __("upcoming", "yatra")} ID: {departure.id}
{/* Key Metrics */} {isLoading ? (
{[...Array(4)].map((_, i) => ( ))}
) : (
{bookedCount}
{__("Bookings", "yatra")}
{maxCapacity}
{__("Total Capacity", "yatra")}
{occupancyRate.toFixed(1)}%
{__("Occupancy Rate", "yatra")}
{formatCurrency(departure.total_revenue || 0)}
{__("Total Revenue", "yatra")}
)}
{/* Tab Navigation */}
{/* Overview Tab */} {activeTab === "overview" && (
{/* Departure Details */}

{__("Departure Information", "yatra")}

{__("Start Date", "yatra")}: {departure.start_date ? formatDate(departure.start_date) : "--"}
{__("End Date", "yatra")}: {departure.end_date ? formatDate(departure.end_date) : "--"}
{__("Departure Time", "yatra")}: {departure.time ? formatTime(departure.time) : "--"}
{__("Duration", "yatra")}: {trip.duration_days || "--"} days
{__("Source", "yatra")}: {departure.source || "Manual"}
{/* Capacity Management */}

{__("Capacity Management", "yatra")}

{__("Occupancy", "yatra")} {occupancyRate.toFixed(1)}%
{bookedCount}
{__("Booked", "yatra")}
{availableSpots}
{__("Available", "yatra")}
{maxCapacity}
{__("Total", "yatra")}
{/* Trip Details */}

{__("Trip Details", "yatra")}

{__("Starting Location", "yatra")}:

{trip.starting_location || "--"}

{__("Ending Location", "yatra")}:

{trip.ending_location || "--"}

{__("Difficulty Level", "yatra")}:

{trip.difficulty_level || "--"}

{__("Group Type", "yatra")}:

{trip.group_type || "--"}

{__("Min Travelers", "yatra")}:

{trip.min_travelers || "--"}

{__("Max Travelers", "yatra")}:

{trip.max_travelers || "--"}

{trip.duration && (
{__("Duration", "yatra")}:

{trip.duration} {__("days", "yatra")}

)} {trip.created_at && (
{__("Trip Created", "yatra")}:

{formatDate(trip.created_at)}

)} {trip.price && (
{__("Base Price", "yatra")}:

{formatCurrency(trip.price)}

)}
{/* Notes */} {departure.notes && (

{__("Notes", "yatra")}

{departure.notes}

)}
)} {/* Bookings Tab */} {activeTab === "bookings" && (

{__("Linked Bookings", "yatra")}

{departure.booking_ids?.length || 0} {__("bookings", "yatra")}
{departure.booking_ids && departure.booking_ids.length > 0 ? (
{departure.booking_ids.map((bookingId: number) => (

{__("Booking", "yatra")} #{bookingId}

{__("Click to view booking details", "yatra")}

{__("Active", "yatra")} View →
))}
) : (

{__("No Bookings Yet", "yatra")}

{__( "This departure doesn't have any linked bookings.", "yatra", )}

)}
)} {/* Travelers Tab */} {activeTab === "travelers" && (

{__("Travelers", "yatra")}

{departure.travelers?.length || 0} {__("travelers", "yatra")}
{departure.travelers && departure.travelers.length > 0 ? (
{departure.travelers.map((traveler: any, index: number) => (

{traveler.first_name} {traveler.last_name} {traveler.is_lead && ( {__("Lead", "yatra")} )}

{traveler.email && ( {traveler.email} )} {traveler.phone && ( {traveler.phone} )}

{traveler.booking_reference && ( Booking #{traveler.booking_reference} )}
))}
) : (

{__("No Travelers Yet", "yatra")}

{__( "No travelers have been assigned to this departure.", "yatra", )}

)}
)} {/* Financials Tab */} {activeTab === "financials" && (

{__("Financial Overview", "yatra")}

{formatCurrency(departure.total_revenue || 0)}
{__("Total Revenue", "yatra")}
{formatCurrency(departure.collected_amount || 0)}
{__("Collected", "yatra")}
{formatCurrency( (departure.total_revenue || 0) - (departure.collected_amount || 0), )}
{__("Pending", "yatra")}
{departure.price_override && (

{__("Price Override Active", "yatra")}

{__("This departure has a custom price of", "yatra")}{" "} {formatCurrency(departure.price_override)} {__("instead of the standard trip price.", "yatra")}

)}
)} {/* Operations Tab */} {activeTab === "operations" && (

{__("Operational Details", "yatra")}

{__("Status Information", "yatra")}

{__("Current Status", "yatra")}: {departure.status || "upcoming"}
{__("Created", "yatra")}: {departure.created_at ? formatDate(departure.created_at) : "--"}
{__("Last Updated", "yatra")}: {departure.updated_at ? formatDate(departure.updated_at) : "--"}
{__("Source", "yatra")}: {departure.source || "Manual"}

{__("Performance Metrics", "yatra")}

{__("Booking Efficiency", "yatra")}: {occupancyRate.toFixed(1)}%
{__("Revenue per Seat", "yatra")}: {formatCurrency( (departure.total_revenue || 0) / Math.max(maxCapacity, 1), )}
{__("Utilization Rate", "yatra")}: {occupancyRate.toFixed(1)}%
)}
); }; export default ViewDeparture;