168 lines
5.6 KiB
JavaScript
168 lines
5.6 KiB
JavaScript
require('dotenv').config();
|
||
const express = require('express');
|
||
const nodemailer = require("nodemailer");
|
||
const { Pool } = require('pg');
|
||
const app = express();
|
||
const PORT = 3000;
|
||
|
||
const transporter = nodemailer.createTransport({
|
||
host: "smtp.gmail.com",
|
||
port: 587,
|
||
secure: false,
|
||
auth: {
|
||
user: process.env.ETHEREAL_USER,
|
||
pass: process.env.ETHEREAL_PASS,
|
||
},
|
||
});
|
||
|
||
// Serve static files
|
||
app.use(express.static('public'));
|
||
app.use(express.json());
|
||
|
||
// PostgreSQL connection
|
||
const pool = new Pool({
|
||
user: process.env.DB_USER,
|
||
host: process.env.DB_HOST,
|
||
database: process.env.DB_DATABASE,
|
||
password: process.env.DB_PASSWORD,
|
||
port: process.env.DB_PORT
|
||
});
|
||
|
||
// Create booking
|
||
app.post('/api/book', async (req, res) => {
|
||
const { name, email, phone, date, time } = req.body;
|
||
try {
|
||
const result = await pool.query(
|
||
`INSERT INTO bookings (name, email, phone, booking_date, booking_time)
|
||
VALUES ($1, $2, $3, $4, $5) RETURNING *`,
|
||
[name, email, phone, date, time]
|
||
);
|
||
|
||
const booking = result.rows[0];
|
||
|
||
// Send confirmation email
|
||
const customerEmail = await transporter.sendMail({
|
||
from: '"Booking System" <no-reply@booking.com>',
|
||
to: email, // send to the customer
|
||
subject: "Booking Request",
|
||
text: `Hi ${name}, your booking request for ${date} at ${time} has been received and is being processed. We will get back to you as soon as possible.`,
|
||
html: `<p>Hi ${name},</p><p>your booking request for <b>${date}</b> at <b>${time}</b> has been received and is being processed. We will get back to you as soon as possible.</p><br>
|
||
<p>Note: This is a test email</p><br>`,
|
||
});
|
||
|
||
const ownerEmail = await transporter.sendMail({
|
||
from: '"Booking System" <no-reply@booking.com>',
|
||
to: email, // send to the admin
|
||
subject: "Booking Request",
|
||
text: `${name} wants to book in for ${date} at ${time}.`,
|
||
html: `<p>${name} wants to book in for ${date} at ${time}.</p><br>
|
||
<p>Please give the customer a response under:<br>
|
||
<a href="https://booking.4l3ks.com/">booking.4l3ks.com</p><br>
|
||
<p>Note: This is a test email</p><br>`,
|
||
});
|
||
|
||
res.json({ reply: "Booking successful!", booking });
|
||
} catch (err) {
|
||
console.error("Error inserting booking:", err);
|
||
res.status(500).json({ reply: "Database error" });
|
||
}
|
||
});
|
||
|
||
// Get all bookings
|
||
app.get('/api/book', async (req, res) => {
|
||
try {
|
||
const result = await pool.query('SELECT * FROM bookings');
|
||
res.json(result.rows);
|
||
} catch (err) {
|
||
console.error("Error fetching bookings:", err);
|
||
res.status(500).send('Database error');
|
||
}
|
||
});
|
||
|
||
// Update booking status
|
||
app.put('/api/book', async (req, res) => {
|
||
const { accepted, id } = req.body;
|
||
try {
|
||
const result = await pool.query(
|
||
`UPDATE bookings
|
||
SET accepted = $1
|
||
WHERE id = $2
|
||
RETURNING *`,
|
||
[accepted, id]
|
||
);
|
||
|
||
if (result.rows.length === 0) {
|
||
return res.status(404).json({ reply: "Booking not found" });
|
||
}
|
||
|
||
const booking = result.rows[0]; // updated booking row
|
||
const { name, email, booking_date, booking_time } = booking;
|
||
|
||
// Send confirmation email only if booking is accepted
|
||
if (accepted) {
|
||
const customerConf = await transporter.sendMail({
|
||
from: '"Booking System" <no-reply@booking.com>',
|
||
to: email, // customer's email from DB
|
||
subject: "Booking Confirmation",
|
||
text: `Hi ${name}, your booking request for ${booking_date} at ${booking_time} has been accepted.`,
|
||
html: `<p>Hi ${name},</p>
|
||
<p>Your booking request for <b>${booking_date}</b> at <b>${booking_time}</b> has been accepted.</p>
|
||
<br><p>Note: This is a test email</p><br>`,
|
||
});
|
||
|
||
console.log("Email sent:", customerConf.messageId);
|
||
console.log("Preview URL:", nodemailer.getTestMessageUrl(customerConf));
|
||
}
|
||
|
||
res.json({ reply: "Booking updated", booking });
|
||
} catch (err) {
|
||
console.error("Error updating booking:", err);
|
||
res.status(500).send("Database error");
|
||
}
|
||
});
|
||
|
||
// Delete booking
|
||
app.delete('/api/book/:id', async (req, res) => {
|
||
const { id } = req.params;
|
||
|
||
try {
|
||
const result = await pool.query(
|
||
`DELETE FROM bookings
|
||
WHERE id = $1
|
||
RETURNING *`,
|
||
[id]
|
||
);
|
||
|
||
if (result.rows.length === 0) {
|
||
return res.status(404).json({ reply: "Booking not found" });
|
||
}
|
||
|
||
const booking = result.rows[0]; // deleted booking data
|
||
const { name, email, booking_date, booking_time } = booking;
|
||
|
||
// Send cancellation email
|
||
const cancelEmail = await transporter.sendMail({
|
||
from: '"Booking System" <no-reply@booking.com>',
|
||
to: email,
|
||
subject: "Booking Cancelled",
|
||
text: `Hi ${name}, your booking for ${booking_date} at ${booking_time} has been cancelled.`,
|
||
html: `<p>Hi ${name},</p>
|
||
<p>We’re letting you know that your booking for <b>${booking_date}</b> at <b>${booking_time}</b> has been <span style="color:red;">cancelled</span>.</p>
|
||
<br><p>Note: This is a test email</p><br>`,
|
||
});
|
||
|
||
console.log("Cancellation email sent:", cancelEmail.messageId);
|
||
console.log("Preview URL:", nodemailer.getTestMessageUrl(cancelEmail));
|
||
|
||
res.json({ reply: "Booking deleted", booking });
|
||
} catch (err) {
|
||
console.error("Error deleting booking:", err);
|
||
res.status(500).send("Database error");
|
||
}
|
||
});
|
||
|
||
|
||
app.listen(PORT, () => {
|
||
console.log(`Server running at http://localhost:${PORT}`);
|
||
});
|