feat: guest reservations and messages

- Remove Reserve button from rooms page
- Calendar modal now supports direct reservation for guests
- Message modal works for guests (asks for name, contact method, contact)
- Add guest_name, guest_contact_method, guest_contact to reservations and messages tables
- LEFT JOIN users in reservations GET to include guest reservations
- Auto-fill form for logged-in users, show input fields for guests
This commit is contained in:
2026-07-01 00:05:39 -05:00
parent 72b507e434
commit ae6ea0ea46
4 changed files with 224 additions and 63 deletions
+20 -7
View File
@@ -5,21 +5,34 @@ import { getSession } from '@/lib/auth';
export async function POST(request: Request) {
try {
const user = await getSession();
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const { room_id, message } = await request.json();
const body = await request.json();
// Support both logged-in users and guests
const { room_id, message, guest_name, guest_contact_method, guest_contact } = body;
if (!message || !message.trim()) {
return NextResponse.json({ error: 'Message is required' }, { status: 400 });
}
const { rows } = await db.query(`
// For guests, require name and contact info
if (!user && (!guest_name || !guest_contact)) {
return NextResponse.json({ error: 'Name and contact info are required' }, { status: 400 });
}
let finalMessage = message.trim();
let finalUserId = user?.id || null;
// For guests, prepend their contact info to the message
if (!user && guest_name && guest_contact) {
const methodLabel = guest_contact_method ? ` (${guest_contact_method})` : '';
finalMessage = `[Guest: ${guest_name}${methodLabel} - ${guest_contact}]\n\n${message.trim()}`;
}
const result = await db.query(`
INSERT INTO messages (room_id, user_id, message)
VALUES ($1, $2, $3)
RETURNING *
`, [room_id || null, user.id, message.trim()]);
`, [room_id || null, finalUserId, finalMessage]);
// Get admin emails for notification
const { rows: admins } = await db.query(`SELECT email, phone FROM users WHERE role = 'admin' AND (email IS NOT NULL OR phone IS NOT NULL)`);
+22 -10
View File
@@ -5,11 +5,13 @@ import { getSession } from '@/lib/auth';
export async function POST(request: Request) {
try {
const user = await getSession();
if (!user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
const body = await request.json();
const { room_id, check_in, check_out, guest_name, guest_contact_method, guest_contact } = body;
const { room_id, check_in, check_out } = await request.json();
// Require either logged-in user or guest info
if (!user && (!guest_name || !guest_contact)) {
return NextResponse.json({ error: 'Please provide your name and contact information' }, { status: 400 });
}
if (!room_id || !check_in || !check_out) {
return NextResponse.json({ error: 'Missing required fields' }, { status: 400 });
@@ -57,12 +59,21 @@ export async function POST(request: Request) {
const pricePerNight = parseFloat(room.price) || 0;
const total_price = nights * pricePerNight;
// Create reservation
// Create reservation - for guests, user_id is NULL
const { rows } = await db.query(`
INSERT INTO reservations (room_id, user_id, check_in, check_out, status, total_price)
VALUES ($1, $2, $3, $4, 'pending', $5)
INSERT INTO reservations (room_id, user_id, check_in, check_out, status, total_price, guest_name, guest_contact_method, guest_contact)
VALUES ($1, $2, $3, $4, 'pending', $5, $6, $7, $8)
RETURNING *
`, [room_id, user.id, check_in, check_out, total_price]);
`, [
room_id,
user?.id || null,
check_in,
check_out,
total_price,
guest_name || null,
guest_contact_method || null,
guest_contact || null,
]);
// Block the dates
const insertPromises = [];
@@ -107,10 +118,11 @@ export async function GET(request: Request) {
const status = searchParams.get('status') || 'all';
let query = `
SELECT r.*, rm.name as room_name, u.username, u.first_name, u.last_name, u.email, u.phone
SELECT r.*, rm.name as room_name,
u.username, u.first_name, u.last_name, u.email, u.phone
FROM reservations r
JOIN rooms rm ON r.room_id = rm.id
JOIN users u ON r.user_id = u.id
LEFT JOIN users u ON r.user_id = u.id
`;
const params: any[] = [];