This commit is contained in:
Iliyan Angelov
2025-11-21 01:20:51 +02:00
parent a38ab4fa82
commit 6f85b8cf17
242 changed files with 7154 additions and 14492 deletions

View File

@@ -86,7 +86,7 @@ const BookingManagementPage: React.FC = () => {
const handleCreateInvoice = async (bookingId: number) => {
try {
setCreatingInvoice(true);
// Ensure bookingId is a number
const invoiceData = {
booking_id: Number(bookingId),
};
@@ -138,7 +138,7 @@ const BookingManagementPage: React.FC = () => {
cancelled: {
bg: 'bg-gradient-to-r from-rose-50 to-red-50',
text: 'text-rose-800',
label: 'Cancelled',
label: 'Canceled',
border: 'border-rose-200'
},
};
@@ -150,14 +150,13 @@ const BookingManagementPage: React.FC = () => {
);
};
if (loading) {
return <Loading />;
}
return (
<div className="space-y-8 bg-gradient-to-br from-slate-50 via-white to-slate-50 min-h-screen -m-6 p-8">
{/* Luxury Header */}
{}
<div className="animate-fade-in">
<div className="flex items-center gap-3 mb-2">
<div className="h-1 w-16 bg-gradient-to-r from-amber-400 to-amber-600 rounded-full"></div>
@@ -168,7 +167,7 @@ const BookingManagementPage: React.FC = () => {
<p className="text-slate-600 mt-3 text-lg font-light">Manage and track all hotel bookings with precision</p>
</div>
{/* Luxury Filter Card */}
{}
<div className="bg-white/80 backdrop-blur-sm rounded-2xl shadow-xl border border-slate-200/60 p-6 animate-fade-in" style={{ animationDelay: '0.1s' }}>
<div className="grid grid-cols-1 md:grid-cols-2 gap-5">
<div className="relative group">
@@ -191,12 +190,12 @@ const BookingManagementPage: React.FC = () => {
<option value="confirmed">Confirmed</option>
<option value="checked_in">Checked in</option>
<option value="checked_out">Checked out</option>
<option value="cancelled">Cancelled</option>
<option value="cancelled">Canceled</option>
</select>
</div>
</div>
{/* Luxury Table Card */}
{}
<div className="bg-white/80 backdrop-blur-sm rounded-2xl shadow-xl border border-slate-200/60 overflow-hidden animate-fade-in" style={{ animationDelay: '0.2s' }}>
<div className="overflow-x-auto">
<table className="w-full">
@@ -348,11 +347,11 @@ const BookingManagementPage: React.FC = () => {
/>
</div>
{/* Luxury Detail Modal */}
{}
{showDetailModal && selectedBooking && (
<div className="fixed inset-0 bg-black/70 backdrop-blur-md flex items-center justify-center z-50 p-4 animate-fade-in">
<div className="bg-white rounded-3xl shadow-2xl w-full max-w-3xl max-h-[90vh] overflow-hidden animate-scale-in border border-slate-200">
{/* Modal Header */}
{}
<div className="bg-gradient-to-r from-slate-900 via-slate-800 to-slate-900 px-8 py-6 border-b border-slate-700">
<div className="flex justify-between items-center">
<div>
@@ -368,10 +367,10 @@ const BookingManagementPage: React.FC = () => {
</div>
</div>
{/* Modal Content */}
{}
<div className="p-8 overflow-y-auto max-h-[calc(90vh-120px)]">
<div className="space-y-6">
{/* Booking Number & Status */}
{}
<div className="grid grid-cols-2 gap-6">
<div className="bg-gradient-to-br from-slate-50 to-white p-5 rounded-xl border border-slate-200">
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wider mb-2 block">Booking Number</label>
@@ -383,7 +382,7 @@ const BookingManagementPage: React.FC = () => {
</div>
</div>
{/* Customer Information */}
{}
<div className="bg-gradient-to-br from-amber-50/50 to-yellow-50/50 p-6 rounded-xl border border-amber-100">
<label className="text-xs font-semibold text-slate-600 uppercase tracking-wider mb-4 block flex items-center gap-2">
<div className="w-1 h-4 bg-gradient-to-b from-amber-400 to-amber-600 rounded-full"></div>
@@ -396,7 +395,7 @@ const BookingManagementPage: React.FC = () => {
</div>
</div>
{/* Room Information */}
{}
<div className="bg-gradient-to-br from-blue-50/50 to-indigo-50/50 p-6 rounded-xl border border-blue-100">
<label className="text-xs font-semibold text-slate-600 uppercase tracking-wider mb-4 block flex items-center gap-2">
<div className="w-1 h-4 bg-gradient-to-b from-blue-400 to-blue-600 rounded-full"></div>
@@ -409,7 +408,7 @@ const BookingManagementPage: React.FC = () => {
</p>
</div>
{/* Dates & Guests */}
{}
<div className="grid grid-cols-2 gap-6">
<div className="bg-gradient-to-br from-slate-50 to-white p-5 rounded-xl border border-slate-200">
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wider mb-2 block">Check-in Date</label>
@@ -426,7 +425,7 @@ const BookingManagementPage: React.FC = () => {
<p className="text-lg font-semibold text-slate-900">{selectedBooking.guest_count} guest{selectedBooking.guest_count !== 1 ? 's' : ''}</p>
</div>
{/* Payment Method & Status */}
{}
<div className="bg-gradient-to-br from-indigo-50/50 to-purple-50/50 p-6 rounded-xl border border-indigo-100">
<label className="text-xs font-semibold text-slate-600 uppercase tracking-wider mb-4 block flex items-center gap-2">
<div className="w-1 h-4 bg-gradient-to-b from-indigo-400 to-indigo-600 rounded-full"></div>
@@ -448,33 +447,31 @@ const BookingManagementPage: React.FC = () => {
<div>
<p className="text-xs text-slate-500 mb-1">Payment Status</p>
<p className={`text-base font-semibold ${
selectedBooking.payment_status === 'paid' || selectedBooking.payment_status === 'completed'
selectedBooking.payment_status === 'paid'
? 'text-green-600'
: selectedBooking.payment_status === 'pending'
? 'text-yellow-600'
: selectedBooking.payment_status === 'refunded'
? 'text-orange-600'
: 'text-red-600'
}`}>
{selectedBooking.payment_status === 'paid' || selectedBooking.payment_status === 'completed'
{selectedBooking.payment_status === 'paid'
? '✅ Paid'
: selectedBooking.payment_status === 'pending'
? '⏳ Pending'
: selectedBooking.payment_status === 'failed'
? '❌ Failed'
: selectedBooking.payment_status || 'Unpaid'}
: selectedBooking.payment_status === 'refunded'
? '💰 Refunded'
: '❌ Unpaid'}
</p>
</div>
</div>
</div>
{/* Service Usages */}
{selectedBooking.service_usages && selectedBooking.service_usages.length > 0 && (
{}
{(selectedBooking as any).service_usages && (selectedBooking as any).service_usages.length > 0 && (
<div className="bg-gradient-to-br from-purple-50/50 to-pink-50/50 p-6 rounded-xl border border-purple-100">
<label className="text-xs font-semibold text-slate-600 uppercase tracking-wider mb-4 block flex items-center gap-2">
<div className="w-1 h-4 bg-gradient-to-b from-purple-400 to-purple-600 rounded-full"></div>
Additional Services
</label>
<div className="space-y-2">
{selectedBooking.service_usages.map((service: any, idx: number) => (
{(selectedBooking as any).service_usages.map((service: any, idx: number) => (
<div key={service.id || idx} className="flex justify-between items-center py-2 border-b border-purple-100 last:border-0">
<div>
<p className="text-sm font-medium text-slate-900">{service.service_name || service.name || 'Service'}</p>
@@ -491,7 +488,7 @@ const BookingManagementPage: React.FC = () => {
</div>
)}
{/* Payment Breakdown */}
{}
{(() => {
const completedPayments = selectedBooking.payments?.filter(
(p) => p.payment_status === 'completed'
@@ -549,7 +546,7 @@ const BookingManagementPage: React.FC = () => {
</div>
</div>
)}
{/* Payment Summary - Always show, even if no payments */}
{}
<div className="bg-gradient-to-br from-green-50 via-emerald-50 to-green-50 p-6 rounded-xl border-2 border-green-200 shadow-lg mb-4">
<label className="text-xs font-semibold text-green-700 uppercase tracking-wider mb-2 block">Amount Paid</label>
<p className="text-3xl font-bold bg-gradient-to-r from-green-600 via-emerald-700 to-green-600 bg-clip-text text-transparent">
@@ -570,7 +567,7 @@ const BookingManagementPage: React.FC = () => {
)}
</div>
{/* Remaining Due - Show prominently if there's remaining balance */}
{}
{remainingDue > 0 && (
<div className="bg-gradient-to-br from-amber-50 via-yellow-50 to-amber-50 p-6 rounded-xl border-2 border-amber-200 shadow-lg mb-4">
<label className="text-xs font-semibold text-amber-700 uppercase tracking-wider mb-2 block">Remaining Due (To be paid)</label>
@@ -585,7 +582,7 @@ const BookingManagementPage: React.FC = () => {
</div>
)}
{/* Total Booking Price - Show as reference */}
{}
<div className="bg-gradient-to-br from-slate-50 to-gray-50 p-6 rounded-xl border-2 border-slate-200 shadow-lg">
<label className="text-xs font-semibold text-slate-600 uppercase tracking-wider mb-2 block">Total Booking Price</label>
<p className="text-2xl font-bold text-slate-700">
@@ -599,7 +596,7 @@ const BookingManagementPage: React.FC = () => {
);
})()}
{/* Booking Metadata */}
{}
<div className="bg-gradient-to-br from-slate-50 to-white p-6 rounded-xl border border-slate-200">
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wider mb-4 block flex items-center gap-2">
<div className="w-1 h-4 bg-gradient-to-b from-slate-400 to-slate-600 rounded-full"></div>
@@ -641,7 +638,7 @@ const BookingManagementPage: React.FC = () => {
</div>
</div>
{/* Notes */}
{}
{selectedBooking.notes && (
<div className="bg-gradient-to-br from-slate-50 to-white p-6 rounded-xl border border-slate-200">
<label className="text-xs font-semibold text-slate-500 uppercase tracking-wider mb-3 block">Special Notes</label>
@@ -650,7 +647,7 @@ const BookingManagementPage: React.FC = () => {
)}
</div>
{/* Modal Footer */}
{}
<div className="mt-8 pt-6 border-t border-slate-200 flex justify-between items-center">
<button
onClick={() => handleCreateInvoice(selectedBooking.id)}