/** * View Enquiry Page * Display enquiry details in a clean, minimal SaaS-style design */ import React, { useMemo, useState } from "react"; import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; import { ArrowLeft, Mail, Phone, Calendar, MessageSquare, Edit, ExternalLink, MapPin, Users, Send, Loader2, } from "lucide-react"; import { __ } from "../lib/i18n"; import { apiService } from "../lib/api-client"; import { usePermissions } from "../hooks/usePermissions"; import { Button } from "../components/ui/button"; import { PageHeader } from "../components/common/PageHeader"; import { Card, CardContent, CardHeader, CardTitle, } from "../components/ui/card"; import { ConditionalRender } from "../components/ui/conditional-render"; import { Badge } from "../components/ui/badge"; import { useNavigate } from "../hooks/useNavigate"; import { Skeleton } from "../components/ui/skeleton"; import { Modal } from "../components/ui/modal"; import { useToast } from "../components/ui/toast"; interface Enquiry { id: number; name: string; email: string; phone?: string; trip_id?: number; trip_title?: string; trip_slug?: string; message: string; travelers_count?: number; travel_date?: string; status: | "new" | "pending" | "responded" | "closed" | "converted" | "" | string; created_at: string; responded_at?: string; response?: string; } const ViewEnquiry: React.FC = () => { const { can } = usePermissions(); const { navigate } = useNavigate(); const queryClient = useQueryClient(); const { showToast } = useToast(); const [respondDialogOpen, setRespondDialogOpen] = useState(false); const [responseMessage, setResponseMessage] = useState(""); // Get enquiry id from URL const enquiryId = useMemo(() => { const params = new URLSearchParams(window.location.search); return params.get("id") ? parseInt(params.get("id") || "0") : null; }, []); // Fetch enquiry data from API const { data: enquiry, isLoading, error, } = useQuery({ queryKey: ["enquiry", enquiryId], queryFn: async () => { if (!enquiryId) return null; const response = await apiService.getEnquiry(enquiryId!); // Some endpoints return { success, data }, others return the object directly return (response as any)?.data ?? response; }, enabled: !!enquiryId && can("yatra_view_bookings"), }); // Respond mutation const respondMutation = useMutation({ mutationFn: async ({ id, message }: { id: number; message: string }) => { return await apiService.respondToEnquiry(id, { response: message }); }, onSuccess: () => { queryClient.invalidateQueries({ queryKey: ["enquiry", enquiryId] }); setRespondDialogOpen(false); setResponseMessage(""); showToast(__("Response sent successfully.", "yatra"), "success"); }, }); const formatDate = (dateString: string) => { return new Date(dateString).toLocaleDateString("en-US", { weekday: "long", year: "numeric", month: "long", day: "numeric", }); }; const getStatusBadge = (status: string) => { const statusMap: Record = { new: { className: "bg-blue-100 text-blue-700 dark:bg-blue-900/20 dark:text-blue-400", label: __("New", "yatra"), }, pending: { className: "bg-orange-100 text-orange-700 dark:bg-orange-900/20 dark:text-orange-400", label: __("Pending", "yatra"), }, responded: { className: "bg-yellow-100 text-yellow-700 dark:bg-yellow-900/20 dark:text-yellow-400", label: __("Responded", "yatra"), }, converted: { className: "bg-green-100 text-green-700 dark:bg-green-900/20 dark:text-green-400", label: __("Converted", "yatra"), }, closed: { className: "bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-400", label: __("Closed", "yatra"), }, }; const statusInfo = statusMap[status] || { className: "bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-400", label: status, }; return ( {statusInfo.label} ); }; const handleBack = () => { navigate({ subpage: "enquiries" }); }; const handleEdit = () => { if (enquiryId) { navigate({ subpage: "enquiries", action: "edit", id: enquiryId }); } }; const handleViewTrip = () => { if (enquiry?.trip_id) { navigate({ subpage: "trips", tab: "all", action: "edit", id: enquiry.trip_id, }); } }; const handleRespond = () => { setResponseMessage(""); setRespondDialogOpen(true); }; const sendResponse = () => { if (enquiryId && responseMessage.trim()) { respondMutation.mutate({ id: enquiryId, message: responseMessage, }); } }; if (isLoading) { return (
} />
); } if (error || !enquiry) { return (
{__("Back to Enquiries", "yatra")} } /> {__( "Enquiry not found or you do not have permission to view it.", "yatra", )}
); } return (
{enquiry.status !== "responded" && enquiry.status !== "closed" && ( )}
} />
{/* Main Content */}
{/* Enquiry Information */}
{__("Enquiry Information", "yatra")} {getStatusBadge(enquiry.status)}

{enquiry.message}

{enquiry.travelers_count && (

{enquiry.travelers_count}

)} {enquiry.travel_date && (

{formatDate(enquiry.travel_date)}

)}
{enquiry.response && (

{enquiry.response}

)}
{/* Trip Information */} {enquiry.trip_title && (
{__("Related Trip", "yatra")} {enquiry.trip_id && ( )}

{enquiry.trip_title}

)}
{/* Sidebar */}
{/* Customer Information */} {__("Customer", "yatra")}

{enquiry.name}

{enquiry.email}
{enquiry.phone && (
{enquiry.phone}
)}
{/* Enquiry Timeline */} {__("Timeline", "yatra")}

{formatDate(enquiry.created_at)}

{enquiry.responded_at && (

{formatDate(enquiry.responded_at)}

)}
{/* Respond Dialog via shared Modal */} { if (!respondMutation.isPending) setRespondDialogOpen(false); }} title={__("Respond to Enquiry", "yatra")} description={ enquiry ? ( {__("Send a response to", "yatra")}{" "} {enquiry.name} ) : null } size="md" footer={
} > {enquiry && (
{/* Customer Info */}
{enquiry.email}
{enquiry.trip_title && (
{enquiry.trip_title}
)}
{__("Original Message:", "yatra")}

{enquiry.message}

{/* Response Message */}