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:
@@ -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)`);
|
||||
|
||||
@@ -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[] = [];
|
||||
|
||||
Reference in New Issue
Block a user