196 lines
6.5 KiB
TypeScript
196 lines
6.5 KiB
TypeScript
import { Button } from "./ui/button";
|
|
import { Card, CardContent, CardHeader, CardTitle } from "./ui/card";
|
|
import { Separator } from "./ui/separator";
|
|
import { Badge } from "./ui/badge";
|
|
import { CheckCircle, MapPin, Calendar, Users, Car, Phone, User } from "lucide-react";
|
|
|
|
interface BookingData {
|
|
pickup: string;
|
|
dropoff: string;
|
|
date: string;
|
|
time: string;
|
|
passengers: string;
|
|
vehicleType: string;
|
|
contactNumber: string;
|
|
contactName: string;
|
|
}
|
|
|
|
interface Vehicle {
|
|
id: string;
|
|
type: string;
|
|
name: string;
|
|
price: number;
|
|
capacity: number;
|
|
rating: number;
|
|
estimatedTime: string;
|
|
features: string[];
|
|
}
|
|
|
|
interface BookingConfirmationProps {
|
|
bookingData: BookingData;
|
|
selectedVehicle: Vehicle;
|
|
onConfirm: () => void;
|
|
onEdit: () => void;
|
|
}
|
|
|
|
export function BookingConfirmation({
|
|
bookingData,
|
|
selectedVehicle,
|
|
onConfirm,
|
|
onEdit,
|
|
}: BookingConfirmationProps) {
|
|
|
|
// --- POST booking data to Vercel backend ---
|
|
const handleConfirm = async () => {
|
|
try {
|
|
const res = await fetch(
|
|
"https://sangwari-backend-6fperqp5u-sangwari-taxis-projects.vercel.app/api/sendBookingEmail",
|
|
{
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
pickup: bookingData.pickup,
|
|
dropoff: bookingData.dropoff,
|
|
date: bookingData.date,
|
|
time: bookingData.time,
|
|
passengers: bookingData.passengers,
|
|
contactName: bookingData.contactName,
|
|
contactNumber: bookingData.contactNumber,
|
|
}),
|
|
}
|
|
);
|
|
|
|
|
|
|
|
|
|
if (res.ok) {
|
|
alert("Booking email sent successfully!");
|
|
onConfirm(); // optional: trigger parent callback
|
|
} else {
|
|
const data = await res.json();
|
|
console.error("Error response:", data);
|
|
alert("Failed to send booking email.");
|
|
}
|
|
} catch (err) {
|
|
console.error("Error sending booking:", err);
|
|
alert("Error sending booking. Check console for details.");
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Card className="w-full max-w-2xl">
|
|
<CardHeader>
|
|
<CardTitle className="flex items-center gap-2">
|
|
<CheckCircle className="h-5 w-5 text-green-500" />
|
|
Confirm Your Booking
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-6">
|
|
{/* Trip Details */}
|
|
<div className="space-y-4">
|
|
<h3>Trip Details</h3>
|
|
<div className="grid gap-3">
|
|
<div className="flex items-center gap-3">
|
|
<MapPin className="h-4 w-4 text-green-500" />
|
|
<div>
|
|
<div className="text-sm text-muted-foreground">Pickup</div>
|
|
<div>{bookingData.pickup}</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<MapPin className="h-4 w-4 text-red-500" />
|
|
<div>
|
|
<div className="text-sm text-muted-foreground">Drop-off</div>
|
|
<div>{bookingData.dropoff}</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<Calendar className="h-4 w-4" />
|
|
<div>
|
|
<div className="text-sm text-muted-foreground">Date & Time</div>
|
|
<div>{new Date(bookingData.date).toLocaleDateString()} at {bookingData.time}</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<Users className="h-4 w-4" />
|
|
<div>
|
|
<div className="text-sm text-muted-foreground">Passengers</div>
|
|
<div>{bookingData.passengers}</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<User className="h-4 w-4" />
|
|
<div>
|
|
<div className="text-sm text-muted-foreground">Contact Name</div>
|
|
<div>{bookingData.contactName}</div>
|
|
</div>
|
|
</div>
|
|
<div className="flex items-center gap-3">
|
|
<Phone className="h-4 w-4" />
|
|
<div>
|
|
<div className="text-sm text-muted-foreground">Contact Number</div>
|
|
<div>{bookingData.contactNumber}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Separator />
|
|
|
|
{/* Vehicle Details */}
|
|
<div className="space-y-4">
|
|
<h3>Selected Vehicle</h3>
|
|
<div className="flex items-center gap-4">
|
|
<div className="w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center">
|
|
<Car className="h-6 w-6 text-gray-600" />
|
|
</div>
|
|
<div className="flex-1">
|
|
<div className="font-medium">{selectedVehicle.name}</div>
|
|
<div className="text-sm text-muted-foreground">
|
|
{selectedVehicle.capacity} passengers • {selectedVehicle.estimatedTime}
|
|
</div>
|
|
<div className="flex gap-1 mt-1">
|
|
{selectedVehicle.features.map((feature, index) => (
|
|
<Badge key={index} variant="secondary" className="text-xs">
|
|
{feature}
|
|
</Badge>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Separator />
|
|
|
|
{/* Booking Info */}
|
|
<div className="space-y-4">
|
|
<h3>Booking Information</h3>
|
|
<div className="flex justify-between items-center p-4 bg-green-50 rounded-lg">
|
|
<span className="font-medium">
|
|
{bookingData.dropoff.includes("Airport Taxi") ? "Airport Taxi Fee" : "Customize Price"}
|
|
</span>
|
|
<span className="text-xl font-semibold text-green-600">
|
|
{bookingData.dropoff.includes("Airport Taxi") ? "₹999" : "Call for Quote"}
|
|
</span>
|
|
</div>
|
|
<div className="text-sm text-muted-foreground text-center">
|
|
{bookingData.dropoff.includes("Airport Taxi")
|
|
? `₹999 fixed rate for airport taxi. Driver will contact you at ${bookingData.contactNumber} for pickup details.`
|
|
: `Driver will contact you at ${bookingData.contactNumber} for final pricing and trip details.`}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Action Buttons */}
|
|
<div className="flex gap-3 pt-4">
|
|
<Button variant="outline" onClick={onEdit} className="flex-1">
|
|
Edit Booking
|
|
</Button>
|
|
<Button onClick={handleConfirm} className="flex-1 bg-green-600 hover:bg-green-700">
|
|
Book Now
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|