From 9286f3e323f35c45a9509f61806358038b28c4c2 Mon Sep 17 00:00:00 2001 From: muken Date: Fri, 3 Jul 2026 00:34:43 -0500 Subject: [PATCH] feat: room status table view with all rooms --- src/app/admin/page.tsx | 330 +++++++++++++++-------------------------- 1 file changed, 123 insertions(+), 207 deletions(-) diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index aac3c9d..f547cfd 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -1814,218 +1814,134 @@ function RoomStatusSection({ onToast }: { onToast: (msg: string, type: 'success' ) : rooms.length === 0 ? ( ) : ( -
- {rooms.map(room => { - const statusColors = getStatusColor(room.clean_status); - const priorityStyle = getPriorityStyle(room.priority); - const isEditing = editingRoom === room.id; - - return ( -
- {/* Header Row */} -
- {/* Room Name & Status */} -
-
- {getStatusIcon(room.clean_status)} - {room.name} -
- {room.is_vip && ( - - โญ VIP + <> + {/* Compact Room Availability Table */} +
+ + + + + + + + + + + + + {rooms.map((room, i) => ( + { setEditingRoom(editingRoom === room.id ? null : room.id); if (editingRoom !== room.id) startEdit(room); }}> + + + + + + + + ))} + +
RoomStatusOccupancyPriorityGuestPrice
+ {room.is_vip && โญ} + {room.name} + + + {getStatusIcon(room.clean_status)} {room.clean_status} - )} - - {room.clean_status} - - - {room.occupancy_status === 'occupied' ? '๐Ÿ›๏ธ Occupied' : '๐Ÿšช Available'} - - - {priorityStyle.icon} {room.priority} - - {room.issues_count > 0 && ( - - โš ๏ธ {room.issues_count} issue{room.issues_count > 1 ? 's' : ''} + + + {room.occupancy_status === 'occupied' ? '๐Ÿ›๏ธ Occupied' : '๐Ÿšช Available'} - )} - - - {/* Price */} -
- ${parseFloat(room.price).toFixed(2)}/night -
- - {/* Edit Button */} - isEditing ? setEditingRoom(null) : startEdit(room)}> - {isEditing ? 'Cancel' : 'Edit'} - - - - {/* Details Row */} -
- {/* Quick Info Grid */} -
- {/* Current Guest */} - {room.current_guest && ( -
- Guest: - {room.current_guest} - {getPaymentBadge(room.payment_status)} -
- )} - - {/* Checkout */} - {room.checkout_date && ( -
- Checkout: - {formatDate(room.checkout_date)} - {room.checkout_time && at {formatTime(room.checkout_time)}} -
- )} - - {/* Last Cleaned */} - {room.last_cleaned && ( -
- Last cleaned: - {formatDateTime(room.last_cleaned)} -
- )} - - {/* Assigned Staff */} - {room.assigned_staff && ( -
- Staff: - {room.assigned_staff.first_name || ''} {room.assigned_staff.last_name || ''} -
- )} -
- - {/* Upcoming Reservations */} - {room.upcoming_reservations && room.upcoming_reservations.length > 0 && ( -
-
Upcoming:
- {room.upcoming_reservations.map((res, i) => ( -
- ๐Ÿ“… {formatDate(res.check_in)} โ†’ {formatDate(res.check_out)} - {res.guest_name || res.first_name || 'Guest'} - {getPaymentBadge(res.payment_status)} -
- ))} +
+ + {getPriorityStyle(room.priority).icon} {room.priority} + + + {room.current_guest ? ( + {room.current_guest} {getPaymentBadge(room.payment_status)} + ) : ( + โ€” + )} + + ${parseFloat(room.price).toFixed(2)} +
+
+ + {/* Detailed Room Cards (click to expand) */} + {editingRoom !== null && ( +
+ {rooms.filter(r => r.id === editingRoom).map(room => { + const isEditing = true; + const statusColors = getStatusColor(room.clean_status); + const priorityStyle = getPriorityStyle(room.priority); + return ( +
+
+

+ {room.is_vip && 'โญ '}{room.name} +

+ setEditingRoom(null)}>Close
- )} - - {/* Notes */} - {room.notes && !isEditing && ( -
- ๐Ÿ“ {room.notes} -
- )} - - {/* Edit Form */} - {isEditing && ( -
-
- setEditData(prev => ({ ...prev, clean_status: v }))} - options={[ - { value: 'clean', label: 'โœจ Clean' }, - { value: 'dirty', label: '๐Ÿงน Dirty' }, - { value: 'maintenance', label: '๐Ÿ”ง Maintenance' }, - ]} - /> - setEditData(prev => ({ ...prev, priority: v }))} - options={[ - { value: 'urgent', label: '๐Ÿ”ด Urgent' }, - { value: 'normal', label: '๐Ÿ”ต Normal' }, - { value: 'low', label: 'โšช Low' }, - ]} - /> - setEditData(prev => ({ ...prev, assigned_staff_id: v ? parseInt(v) : null }))} - options={[ - { value: '', label: 'โ€” Unassigned โ€”' }, - ...staff.map(s => ({ value: s.id.toString(), label: `${s.first_name || ''} ${s.last_name || ''}`.trim() || s.username })) - ]} - /> -
-
- setEditData(prev => ({ ...prev, issues_count: parseInt(v) || 0 }))} - placeholder="0" - /> - setEditData(prev => ({ ...prev, checkout_date: v }))} - /> - setEditData(prev => ({ ...prev, checkout_time: v }))} - /> -
- - setEditData(prev => ({ ...prev, notes: v }))} - rows={2} - placeholder="e.g., Need extra towels, AC broken..." +
+ setEditData(prev => ({ ...prev, clean_status: v }))} + options={[ + { value: 'clean', label: 'โœจ Clean' }, + { value: 'dirty', label: '๐Ÿงน Dirty' }, + { value: 'maintenance', label: '๐Ÿ”ง Maintenance' }, + ]} + /> + setEditData(prev => ({ ...prev, priority: v }))} + options={[ + { value: 'urgent', label: '๐Ÿ”ด Urgent' }, + { value: 'normal', label: '๐Ÿ”ต Normal' }, + { value: 'low', label: 'โšช Low' }, + ]} + /> + setEditData(prev => ({ ...prev, assigned_staff_id: v ? parseInt(v) : null }))} + options={[ + { value: '', label: 'โ€” Unassigned โ€”' }, + ...staff.map(s => ({ value: s.id.toString(), label: `${s.first_name || ''} ${s.last_name || ''}`.trim() || s.username })) + ]} /> -
- Save - setEditingRoom(null)} size="sm">Cancel -
- )} -
-
- ); - })} -
+
+ setEditData(prev => ({ ...prev, issues_count: parseInt(v) || 0 }))} placeholder="0" /> + setEditData(prev => ({ ...prev, checkout_date: v }))} /> + setEditData(prev => ({ ...prev, checkout_time: v }))} /> +
+ + setEditData(prev => ({ ...prev, notes: v }))} rows={2} placeholder="e.g., Need extra towels, AC broken..." style={{ marginTop: '12px' }} /> +
+ Save + setEditingRoom(null)} size="sm">Cancel +
+ {room.upcoming_reservations && room.upcoming_reservations.length > 0 && ( +
+
๐Ÿ“… Upcoming Reservations
+ {room.upcoming_reservations.map((res, i) => ( +
+ {formatDate(res.check_in)} โ†’ {formatDate(res.check_out)}: {res.guest_name || res.first_name || 'Guest'} +
+ ))} +
+ )} +
+ ); + })} +
+ )} + )}
);