808 lines
25 KiB
TypeScript
808 lines
25 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import {
|
|
useParams,
|
|
useNavigate,
|
|
Link
|
|
} from 'react-router-dom';
|
|
import {
|
|
CheckCircle,
|
|
Home,
|
|
ListOrdered,
|
|
Calendar,
|
|
Users,
|
|
CreditCard,
|
|
MapPin,
|
|
Mail,
|
|
Phone,
|
|
User,
|
|
FileText,
|
|
Building2,
|
|
AlertCircle,
|
|
Copy,
|
|
Check,
|
|
Loader2,
|
|
} from 'lucide-react';
|
|
import { toast } from 'react-toastify';
|
|
import {
|
|
getBookingById,
|
|
generateQRCode,
|
|
type Booking,
|
|
} from '../../services/api/bookingService';
|
|
import { confirmBankTransfer } from
|
|
'../../services/api/paymentService';
|
|
import Loading from '../../components/common/Loading';
|
|
import { useFormatCurrency } from '../../hooks/useFormatCurrency';
|
|
import { parseDateLocal } from '../../utils/format';
|
|
|
|
const BookingSuccessPage: React.FC = () => {
|
|
const { id } = useParams<{ id: string }>();
|
|
const navigate = useNavigate();
|
|
const { formatCurrency } = useFormatCurrency();
|
|
|
|
const [booking, setBooking] = useState<Booking | null>(
|
|
null
|
|
);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [copiedBookingNumber, setCopiedBookingNumber] =
|
|
useState(false);
|
|
const [uploadingReceipt, setUploadingReceipt] =
|
|
useState(false);
|
|
const [receiptUploaded, setReceiptUploaded] =
|
|
useState(false);
|
|
const [selectedFile, setSelectedFile] =
|
|
useState<File | null>(null);
|
|
const [previewUrl, setPreviewUrl] =
|
|
useState<string | null>(null);
|
|
|
|
useEffect(() => {
|
|
if (id) {
|
|
fetchBookingDetails(Number(id));
|
|
}
|
|
}, [id]);
|
|
|
|
const fetchBookingDetails = async (bookingId: number) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
|
|
const response = await getBookingById(bookingId);
|
|
|
|
if (
|
|
response.success &&
|
|
response.data?.booking
|
|
) {
|
|
const bookingData = response.data.booking;
|
|
setBooking(bookingData);
|
|
|
|
|
|
if (bookingData.payment_method === 'stripe' && bookingData.payments) {
|
|
const pendingStripePayment = bookingData.payments.find(
|
|
(p: any) =>
|
|
p.payment_method === 'stripe' &&
|
|
p.payment_status === 'pending'
|
|
);
|
|
|
|
if (pendingStripePayment) {
|
|
|
|
navigate(`/payment/${bookingId}`, { replace: true });
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
if (
|
|
bookingData.requires_deposit &&
|
|
!bookingData.deposit_paid
|
|
) {
|
|
navigate(`/deposit-payment/${bookingId}`, { replace: true });
|
|
return;
|
|
}
|
|
} else {
|
|
throw new Error(
|
|
'Unable to load booking information'
|
|
);
|
|
}
|
|
} catch (err: any) {
|
|
console.error('Error fetching booking:', err);
|
|
const message =
|
|
err.response?.data?.message ||
|
|
'Unable to load booking information';
|
|
setError(message);
|
|
toast.error(message);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
const formatDate = (dateString: string) => {
|
|
|
|
const date = parseDateLocal(dateString);
|
|
return date.toLocaleDateString('en-US', {
|
|
weekday: 'long',
|
|
year: 'numeric',
|
|
month: 'long',
|
|
day: 'numeric',
|
|
});
|
|
};
|
|
|
|
const formatPrice = (price: number) => formatCurrency(price);
|
|
|
|
const getStatusColor = (status: string) => {
|
|
switch (status) {
|
|
case 'confirmed':
|
|
return 'bg-green-100 text-green-800';
|
|
case 'pending':
|
|
return 'bg-yellow-100 text-yellow-800';
|
|
case 'cancelled':
|
|
return 'bg-red-100 text-red-800';
|
|
case 'checked_in':
|
|
return 'bg-blue-100 text-blue-800';
|
|
case 'checked_out':
|
|
return 'bg-gray-100 text-gray-800';
|
|
default:
|
|
return 'bg-gray-100 text-gray-800';
|
|
}
|
|
};
|
|
|
|
const getStatusText = (status: string) => {
|
|
switch (status) {
|
|
case 'confirmed':
|
|
return 'Confirmed';
|
|
case 'pending':
|
|
return 'Pending confirmation';
|
|
case 'cancelled':
|
|
return 'Cancelled';
|
|
case 'checked_in':
|
|
return 'Checked in';
|
|
case 'checked_out':
|
|
return 'Checked out';
|
|
default:
|
|
return status;
|
|
}
|
|
};
|
|
|
|
const copyBookingNumber = async () => {
|
|
if (!booking?.booking_number) return;
|
|
|
|
try {
|
|
await navigator.clipboard.writeText(
|
|
booking.booking_number
|
|
);
|
|
setCopiedBookingNumber(true);
|
|
toast.success('Booking number copied');
|
|
setTimeout(() => setCopiedBookingNumber(false), 2000);
|
|
} catch (err) {
|
|
toast.error('Unable to copy');
|
|
}
|
|
};
|
|
|
|
const handleFileSelect = (
|
|
e: React.ChangeEvent<HTMLInputElement>
|
|
) => {
|
|
const file = e.target.files?.[0];
|
|
if (!file) return;
|
|
|
|
|
|
if (!file.type.startsWith('image/')) {
|
|
toast.error('Please select an image file');
|
|
return;
|
|
}
|
|
|
|
|
|
if (file.size > 5 * 1024 * 1024) {
|
|
toast.error('Image size must not exceed 5MB');
|
|
return;
|
|
}
|
|
|
|
setSelectedFile(file);
|
|
|
|
|
|
const reader = new FileReader();
|
|
reader.onloadend = () => {
|
|
setPreviewUrl(reader.result as string);
|
|
};
|
|
reader.readAsDataURL(file);
|
|
};
|
|
|
|
const handleUploadReceipt = async () => {
|
|
if (!selectedFile || !booking) return;
|
|
|
|
try {
|
|
setUploadingReceipt(true);
|
|
|
|
|
|
const transactionId =
|
|
`TXN-${booking.booking_number}-${Date.now()}`;
|
|
|
|
const response = await confirmBankTransfer(
|
|
booking.id,
|
|
transactionId,
|
|
selectedFile
|
|
);
|
|
|
|
if (response.success) {
|
|
toast.success(
|
|
'✅ Payment confirmation sent successfully! ' +
|
|
'We will confirm as soon as possible.'
|
|
);
|
|
setReceiptUploaded(true);
|
|
|
|
|
|
setBooking((prev) =>
|
|
prev
|
|
? {
|
|
...prev,
|
|
payment_status: 'paid',
|
|
status: prev.status === 'pending'
|
|
? 'confirmed'
|
|
: prev.status
|
|
}
|
|
: null
|
|
);
|
|
} else {
|
|
throw new Error(
|
|
response.message ||
|
|
'Unable to confirm payment'
|
|
);
|
|
}
|
|
} catch (err: any) {
|
|
console.error('Error uploading receipt:', err);
|
|
const message =
|
|
err.response?.data?.message ||
|
|
'Unable to send payment confirmation. ' +
|
|
'Please try again.';
|
|
toast.error(message);
|
|
} finally {
|
|
setUploadingReceipt(false);
|
|
}
|
|
};
|
|
|
|
const qrCodeUrl = booking
|
|
? generateQRCode(
|
|
booking.booking_number,
|
|
booking.total_price
|
|
)
|
|
: null;
|
|
|
|
if (loading) {
|
|
return <Loading fullScreen text="Loading..." />;
|
|
}
|
|
|
|
if (error || !booking) {
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 py-8">
|
|
<div className="max-w-4xl mx-auto px-4">
|
|
<div
|
|
className="bg-red-50 border border-red-200
|
|
rounded-lg p-8 text-center"
|
|
>
|
|
<AlertCircle
|
|
className="w-12 h-12 text-red-500
|
|
mx-auto mb-3"
|
|
/>
|
|
<p className="text-red-700 font-medium mb-4">
|
|
{error || 'Booking not found'}
|
|
</p>
|
|
<button
|
|
onClick={() => navigate('/rooms')}
|
|
className="inline-flex items-center gap-2 bg-indigo-600
|
|
text-white px-3 py-2 rounded-md hover:bg-indigo-700
|
|
disabled:bg-gray-400 mb-6 transition-colors"
|
|
>
|
|
Back to room list
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const room = booking.room;
|
|
const roomType = room?.room_type;
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 py-8">
|
|
<div className="max-w-4xl mx-auto px-4">
|
|
{}
|
|
<div
|
|
className="bg-white rounded-lg shadow-md
|
|
p-8 mb-6 text-center"
|
|
>
|
|
<div
|
|
className="w-20 h-20 bg-green-100
|
|
rounded-full flex items-center
|
|
justify-center mx-auto mb-4"
|
|
>
|
|
<CheckCircle
|
|
className="w-12 h-12 text-green-600"
|
|
/>
|
|
</div>
|
|
<h1
|
|
className="text-3xl font-bold text-gray-900
|
|
mb-2"
|
|
>
|
|
Booking Successful!
|
|
</h1>
|
|
<p className="text-gray-600 mb-4">
|
|
Thank you for booking with our hotel
|
|
</p>
|
|
|
|
{}
|
|
<div
|
|
className="inline-flex items-center gap-2
|
|
bg-indigo-50 px-6 py-3 rounded-lg"
|
|
>
|
|
<span className="text-sm text-indigo-600
|
|
font-medium"
|
|
>
|
|
Booking Number:
|
|
</span>
|
|
<span className="text-lg font-bold
|
|
text-indigo-900"
|
|
>
|
|
{booking.booking_number}
|
|
</span>
|
|
<button
|
|
onClick={copyBookingNumber}
|
|
className="ml-2 p-1 hover:bg-indigo-100
|
|
rounded transition-colors"
|
|
title="Copy booking number"
|
|
>
|
|
{copiedBookingNumber ? (
|
|
<Check className="w-4 h-4 text-green-600" />
|
|
) : (
|
|
<Copy className="w-4 h-4 text-indigo-600" />
|
|
)}
|
|
</button>
|
|
</div>
|
|
|
|
{}
|
|
<div className="mt-4">
|
|
<span
|
|
className={`inline-block px-4 py-2
|
|
rounded-full text-sm font-medium
|
|
${getStatusColor(booking.status)}`}
|
|
>
|
|
{getStatusText(booking.status)}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
{}
|
|
<div className="bg-white rounded-lg shadow-md
|
|
p-6 mb-6"
|
|
>
|
|
<h2 className="text-xl font-bold text-gray-900
|
|
mb-4"
|
|
>
|
|
Booking Details
|
|
</h2>
|
|
|
|
<div className="space-y-4">
|
|
{}
|
|
{roomType && (
|
|
<div className="border-b pb-4">
|
|
<div className="flex items-start gap-4">
|
|
{((room?.room_type?.images && room.room_type.images.length > 0)
|
|
? room.room_type.images[0]
|
|
: roomType?.images?.[0]) && (
|
|
<img
|
|
src={(room?.room_type?.images && room.room_type.images.length > 0)
|
|
? room.room_type.images[0]
|
|
: (roomType?.images?.[0] || '')}
|
|
alt={roomType?.name || 'Room'}
|
|
className="w-24 h-24 object-cover
|
|
rounded-lg"
|
|
/>
|
|
)}
|
|
<div className="flex-1">
|
|
<h3 className="font-bold text-lg
|
|
text-gray-900"
|
|
>
|
|
{roomType.name}
|
|
</h3>
|
|
{room && (
|
|
<p className="text-gray-600 text-sm">
|
|
<MapPin className="w-4 h-4
|
|
inline mr-1"
|
|
/>
|
|
Room {room.room_number} -
|
|
Floor {room.floor}
|
|
</p>
|
|
)}
|
|
<p className="text-indigo-600
|
|
font-semibold mt-1"
|
|
>
|
|
{formatPrice(room?.room_type?.base_price || roomType?.base_price || 0)}/night
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{}
|
|
<div className="grid grid-cols-1 md:grid-cols-2
|
|
gap-4"
|
|
>
|
|
<div>
|
|
<p className="text-sm text-gray-600 mb-1">
|
|
<Calendar className="w-4 h-4 inline mr-1" />
|
|
Check-in Date
|
|
</p>
|
|
<p className="font-medium text-gray-900">
|
|
{formatDate(booking.check_in_date)}
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-sm text-gray-600 mb-1">
|
|
<Calendar className="w-4 h-4 inline mr-1" />
|
|
Check-out Date
|
|
</p>
|
|
<p className="font-medium text-gray-900">
|
|
{formatDate(booking.check_out_date)}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
{}
|
|
<div>
|
|
<p className="text-sm text-gray-600 mb-1">
|
|
<Users className="w-4 h-4 inline mr-1" />
|
|
Number of Guests
|
|
</p>
|
|
<p className="font-medium text-gray-900">
|
|
{booking.guest_count} guest(s)
|
|
</p>
|
|
</div>
|
|
|
|
{}
|
|
{booking.notes && (
|
|
<div>
|
|
<p className="text-sm text-gray-600 mb-1">
|
|
<FileText className="w-4 h-4 inline mr-1" />
|
|
Notes
|
|
</p>
|
|
<p className="font-medium text-gray-900">
|
|
{booking.notes}
|
|
</p>
|
|
</div>
|
|
)}
|
|
|
|
{}
|
|
<div className="border-t pt-4">
|
|
<p className="text-sm text-gray-600 mb-1">
|
|
<CreditCard className="w-4 h-4 inline mr-1" />
|
|
Payment Method
|
|
</p>
|
|
<p className="font-medium text-gray-900">
|
|
{booking.payment_method === 'cash'
|
|
? '💵 Pay at hotel'
|
|
: '🏦 Bank transfer'}
|
|
</p>
|
|
</div>
|
|
|
|
{}
|
|
<div className="border-t pt-4">
|
|
{booking.original_price && booking.discount_amount && booking.discount_amount > 0 ? (
|
|
<>
|
|
<div className="mb-2">
|
|
<div className="flex justify-between items-center mb-1">
|
|
<span className="text-sm text-gray-600">Subtotal:</span>
|
|
<span className="text-base font-semibold text-gray-900">{formatPrice(booking.original_price)}</span>
|
|
</div>
|
|
<div className="flex justify-between items-center mb-2">
|
|
<span className="text-sm text-green-600">
|
|
Discount{booking.promotion_code ? ` (${booking.promotion_code})` : ''}:
|
|
</span>
|
|
<span className="text-base font-semibold text-green-600">-{formatPrice(booking.discount_amount)}</span>
|
|
</div>
|
|
<div className="border-t border-gray-300 pt-2 mt-2">
|
|
<div className="flex justify-between items-center">
|
|
<span className="text-lg font-semibold text-gray-900">Total Payment</span>
|
|
<span className="text-2xl font-bold text-indigo-600">{formatPrice(booking.total_price)}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</>
|
|
) : (
|
|
<div className="flex justify-between items-center">
|
|
<span className="text-lg font-semibold text-gray-900">Total Payment</span>
|
|
<span className="text-2xl font-bold text-indigo-600">{formatPrice(booking.total_price)}</span>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{}
|
|
{booking.guest_info && (
|
|
<div className="bg-white rounded-lg shadow-md
|
|
p-6 mb-6"
|
|
>
|
|
<h2 className="text-xl font-bold text-gray-900
|
|
mb-4"
|
|
>
|
|
Customer Information
|
|
</h2>
|
|
<div className="space-y-3">
|
|
<div>
|
|
<p className="text-sm text-gray-600">
|
|
<User className="w-4 h-4 inline mr-1" />
|
|
Full Name
|
|
</p>
|
|
<p className="font-medium text-gray-900">
|
|
{booking.guest_info.full_name}
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-sm text-gray-600">
|
|
<Mail className="w-4 h-4 inline mr-1" />
|
|
Email
|
|
</p>
|
|
<p className="font-medium text-gray-900">
|
|
{booking.guest_info.email}
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<p className="text-sm text-gray-600">
|
|
<Phone className="w-4 h-4 inline mr-1" />
|
|
Phone Number
|
|
</p>
|
|
<p className="font-medium text-gray-900">
|
|
{booking.guest_info.phone}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{}
|
|
{(booking.payment_method === 'cash' || (booking as any).payment_method === 'bank_transfer') && (
|
|
<div
|
|
className="bg-blue-50 border border-blue-200
|
|
rounded-lg p-6 mb-6"
|
|
>
|
|
<div className="flex items-start gap-3 mb-4">
|
|
<Building2
|
|
className="w-6 h-6 text-blue-600
|
|
mt-1 flex-shrink-0"
|
|
/>
|
|
<div className="flex-1">
|
|
<h3 className="font-bold text-blue-900 mb-2">
|
|
Bank Transfer Instructions
|
|
</h3>
|
|
<div className="space-y-2 text-sm
|
|
text-blue-800"
|
|
>
|
|
<p>
|
|
Please transfer according to the following information:
|
|
</p>
|
|
|
|
<div className="grid grid-cols-1
|
|
md:grid-cols-2 gap-4"
|
|
>
|
|
{}
|
|
<div className="bg-white rounded-lg
|
|
p-4 space-y-2"
|
|
>
|
|
<p>
|
|
<strong>Bank:</strong>
|
|
Vietcombank (VCB)
|
|
</p>
|
|
<p>
|
|
<strong>Account Number:</strong>
|
|
0123456789
|
|
</p>
|
|
<p>
|
|
<strong>Account Holder:</strong>
|
|
KHACH SAN ABC
|
|
</p>
|
|
<p>
|
|
<strong>Amount:</strong>{' '}
|
|
<span className="text-indigo-600
|
|
font-bold"
|
|
>
|
|
{formatPrice(booking.total_price)}
|
|
</span>
|
|
</p>
|
|
<p>
|
|
<strong>Content:</strong>{' '}
|
|
<span className="font-mono
|
|
text-indigo-600"
|
|
>
|
|
{booking.booking_number}
|
|
</span>
|
|
</p>
|
|
</div>
|
|
|
|
{}
|
|
{qrCodeUrl && (
|
|
<div className="bg-white rounded-lg
|
|
p-4 flex flex-col items-center
|
|
justify-center"
|
|
>
|
|
<p className="text-sm font-medium
|
|
text-gray-700 mb-2"
|
|
>
|
|
Scan QR code to transfer
|
|
</p>
|
|
<img
|
|
src={qrCodeUrl}
|
|
alt="QR Code"
|
|
className="w-48 h-48 border-2
|
|
border-gray-200 rounded-lg"
|
|
/>
|
|
<p className="text-xs text-gray-500
|
|
mt-2 text-center"
|
|
>
|
|
QR code includes all information
|
|
</p>
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<p className="text-xs italic mt-2">
|
|
💡 Note: Please enter the correct booking number
|
|
in the transfer content so we can confirm your payment.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{}
|
|
{!receiptUploaded ? (
|
|
<div className="border-t border-blue-200
|
|
pt-4"
|
|
>
|
|
<h4 className="font-semibold text-blue-900
|
|
mb-3"
|
|
>
|
|
📎 Payment Confirmation
|
|
</h4>
|
|
<p className="text-sm text-blue-700 mb-3">
|
|
After transferring, please upload
|
|
the receipt image so we can confirm faster.
|
|
</p>
|
|
|
|
<div className="space-y-3">
|
|
{}
|
|
<div>
|
|
<label
|
|
htmlFor="receipt-upload"
|
|
className="block w-full px-4 py-3
|
|
border-2 border-dashed
|
|
border-blue-300 rounded-lg
|
|
text-center cursor-pointer
|
|
hover:border-blue-400
|
|
hover:bg-blue-100/50
|
|
transition-colors"
|
|
>
|
|
<input
|
|
id="receipt-upload"
|
|
type="file"
|
|
accept="image}
|
|
{selectedFile && (
|
|
<button
|
|
onClick={handleUploadReceipt}
|
|
disabled={uploadingReceipt}
|
|
className="w-full px-4 py-3
|
|
bg-blue-600 text-white
|
|
rounded-lg hover:bg-blue-700
|
|
transition-colors font-semibold
|
|
disabled:bg-gray-400
|
|
disabled:cursor-not-allowed
|
|
flex items-center
|
|
justify-center gap-2"
|
|
>
|
|
{uploadingReceipt ? (
|
|
<>
|
|
<Loader2
|
|
className="w-5 h-5
|
|
animate-spin"
|
|
/>
|
|
Sending...
|
|
</>
|
|
) : (
|
|
<>
|
|
<CheckCircle
|
|
className="w-5 h-5"
|
|
/>
|
|
Confirm payment completed
|
|
</>
|
|
)}
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
) : (
|
|
<div className="border-t border-green-200
|
|
pt-4 bg-green-50 rounded-lg p-4"
|
|
>
|
|
<div className="flex items-center
|
|
gap-3"
|
|
>
|
|
<CheckCircle
|
|
className="w-6 h-6 text-green-600
|
|
flex-shrink-0"
|
|
/>
|
|
<div>
|
|
<p className="font-semibold
|
|
text-green-900"
|
|
>
|
|
Payment confirmation sent
|
|
</p>
|
|
<p className="text-sm text-green-700">
|
|
We will confirm your order
|
|
as soon as possible.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
)}
|
|
|
|
{}
|
|
<div
|
|
className="bg-yellow-50 border border-yellow-200
|
|
rounded-lg p-4 mb-6"
|
|
>
|
|
<p className="text-sm text-yellow-800">
|
|
⚠️ <strong>Important Notice:</strong>
|
|
</p>
|
|
<ul className="text-sm text-yellow-700 mt-2
|
|
space-y-1 ml-4 list-disc"
|
|
>
|
|
<li>
|
|
Please bring your ID card when checking in
|
|
</li>
|
|
<li>
|
|
Check-in time: 14:00 /
|
|
Check-out time: 12:00
|
|
</li>
|
|
<li>
|
|
If you cancel the booking, 20% of
|
|
the total order value will be charged
|
|
</li>
|
|
{(booking.payment_method === 'cash' || (booking as any).payment_method === 'bank_transfer') && (
|
|
<li>
|
|
Please transfer within 24 hours
|
|
to secure your room
|
|
</li>
|
|
)}
|
|
</ul>
|
|
</div>
|
|
|
|
{}
|
|
<div className="flex flex-col sm:flex-row gap-4">
|
|
<Link
|
|
to="/bookings"
|
|
className="flex-1 flex items-center
|
|
justify-center gap-2 px-6 py-3
|
|
bg-indigo-600 text-white rounded-lg
|
|
hover:bg-indigo-700 transition-colors
|
|
font-semibold"
|
|
>
|
|
<ListOrdered className="w-5 h-5" />
|
|
View My Bookings
|
|
</Link>
|
|
<Link
|
|
to="/"
|
|
className="flex-1 flex items-center
|
|
justify-center gap-2 px-6 py-3
|
|
bg-gray-600 text-white rounded-lg
|
|
hover:bg-gray-700 transition-colors
|
|
font-semibold"
|
|
>
|
|
<Home className="w-5 h-5" />
|
|
Go to Home
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default BookingSuccessPage;
|