Files
hotel777/server.js
2026-05-03 16:47:27 +05:00

109 lines
4.0 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const express = require('express');
const path = require('path');
const fs = require('fs');
const sqlite3 = require('sqlite3').verbose();
const sharp = require('sharp');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 3000;
const API_KEY = process.env.HOTEL777KEY;
if (!API_KEY) {
console.error('FATAL: HOTEL777KEY environment variable not set');
process.exit(1);
}
// Middleware
app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));
// Ensure data directory and database
const dataDir = path.join(__dirname, 'data');
if (!fs.existsSync(dataDir)) fs.mkdirSync(dataDir);
const dbPath = path.join(dataDir, 'bookings.db');
const db = new sqlite3.Database(dbPath);
db.run(`CREATE TABLE IF NOT EXISTS bookings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
phone TEXT NOT NULL,
adults INTEGER NOT NULL,
children INTEGER NOT NULL,
checkin_date TEXT NOT NULL,
checkout_date TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
)`);
// Image conversion (automatically convert JPEG/PNG to WebP)
async function convertImages() {
const imgDir = path.join(__dirname, 'public', 'img');
if (!fs.existsSync(imgDir)) {
console.log('Папка img не найдена, пропускаем конвертацию.');
return;
}
const files = fs.readdirSync(imgDir);
for (const file of files) {
const ext = path.extname(file).toLowerCase();
if (ext === '.jpg' || ext === '.jpeg' || ext === '.png') {
const name = path.parse(file).name;
const webpPath = path.join(imgDir, `${name}.webp`);
if (!fs.existsSync(webpPath)) {
try {
await sharp(path.join(imgDir, file))
.webp({ quality: 85 })
.toFile(webpPath);
console.log(`✅ Сконвертировано: ${file} -> ${name}.webp`);
} catch (err) {
console.error(`❌ Ошибка при конвертации ${file}:`, err);
}
}
}
}
}
// API: POST /api/bookings сохранить новую заявку
app.post('/api/bookings', (req, res) => {
const { name, phone, adults, children, checkin, checkout } = req.body;
if (!name || !phone || !adults || !checkin || !checkout) {
return res.status(400).json({ error: 'Missing required fields' });
}
const stmt = db.prepare(`INSERT INTO bookings (name, phone, adults, children, checkin_date, checkout_date)
VALUES (?, ?, ?, ?, ?, ?)`);
stmt.run(name, phone, adults, children || 0, checkin, checkout, function(err) {
if (err) {
console.error(err);
return res.status(500).json({ error: 'Database error' });
}
res.status(201).json({ id: this.lastID, message: 'Booking saved' });
});
stmt.finalize();
});
// API: GET /api/bookings получить список всех заявок (требуется API-ключ)
app.get('/api/bookings', (req, res) => {
const providedKey = req.headers['x-api-key'];
if (!providedKey || providedKey !== API_KEY) {
return res.status(401).json({ error: 'Invalid or missing API key' });
}
db.all(`SELECT id, name, phone, adults, children, checkin_date, checkout_date, created_at
FROM bookings ORDER BY created_at DESC`, (err, rows) => {
if (err) {
console.error(err);
return res.status(500).json({ error: 'Database error' });
}
res.json(rows);
});
});
// Serve frontend
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
// Start server after image conversion
convertImages().then(() => {
app.listen(PORT, () => {
console.log('✅ HOTEL777KEY is', API_KEY);
console.log(`✅ Hotel 777 server running on http://localhost:${PORT}`);
});
});