Отзывы
This commit is contained in:
133
server.js
133
server.js
@@ -203,6 +203,50 @@ db.serialize(() => {
|
||||
role TEXT NOT NULL DEFAULT 'user',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)`);
|
||||
db.run(`CREATE TABLE IF NOT EXISTS settings (
|
||||
key TEXT PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)`, (err) => {
|
||||
if (err) {
|
||||
console.error('CREATE TABLE settings FAILED:', err.message);
|
||||
} else {
|
||||
console.log('CREATE TABLE settings SUCCESS');
|
||||
}
|
||||
});
|
||||
|
||||
db.run(`CREATE TABLE IF NOT EXISTS reviews (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
author_name TEXT NOT NULL,
|
||||
country TEXT NOT NULL,
|
||||
country_code TEXT,
|
||||
city TEXT NOT NULL,
|
||||
stars REAL NOT NULL CHECK(stars >= 0 AND stars <= 5),
|
||||
text TEXT NOT NULL,
|
||||
review_code TEXT NOT NULL,
|
||||
ip_address TEXT,
|
||||
is_approved INTEGER DEFAULT 0,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
)`, (err) => {
|
||||
if (err && !err.message.includes('already exists')) {
|
||||
console.error('Reviews table error:', err.message);
|
||||
}
|
||||
|
||||
db.run(`PRAGMA foreign_keys = ON`, (err) => {
|
||||
if (err) console.error('Foreign keys error:', err.message);
|
||||
});
|
||||
|
||||
db.all("PRAGMA table_info(reviews)", [], (err, cols) => {
|
||||
if (err || !cols) return;
|
||||
const colNames = cols.map(c => c.name);
|
||||
if (!colNames.includes('country_code')) {
|
||||
db.run("ALTER TABLE reviews ADD COLUMN country_code TEXT", (err) => {
|
||||
if (err) console.log('Migration: country_code column (ignore if exists):', err.message);
|
||||
else console.log('Migration: country_code column added');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
const modules = {};
|
||||
@@ -213,6 +257,9 @@ const adminBookingsModule = require('./modules/adminBookings');
|
||||
const promocodesModule = require('./modules/promocodes');
|
||||
const roomsModule = require('./modules/rooms');
|
||||
const usersModule = require('./modules/users');
|
||||
const settingsModule = require('./modules/settings');
|
||||
const reviewsModule = require('./modules/reviews');
|
||||
const translationsModule = require('./modules/translations');
|
||||
const { runStartupTests } = require('./tests/runStartupTests');
|
||||
|
||||
modules.auth = authModule;
|
||||
@@ -221,6 +268,9 @@ modules.promocodes = promocodesModule;
|
||||
modules.rooms = roomsModule;
|
||||
modules.users = usersModule;
|
||||
modules.adminBookings = adminBookingsModule;
|
||||
modules.settings = settingsModule;
|
||||
modules.reviews = reviewsModule;
|
||||
modules.translations = translationsModule;
|
||||
|
||||
authModule.init(db, JWT_SECRET);
|
||||
bookingsModule.init(db);
|
||||
@@ -228,6 +278,8 @@ adminBookingsModule.init(db);
|
||||
promocodesModule.init(db);
|
||||
roomsModule.init(db);
|
||||
usersModule.init(db, bcrypt);
|
||||
settingsModule.init(db);
|
||||
reviewsModule.init(db, settingsModule);
|
||||
|
||||
function initDefaultRooms() {
|
||||
db.get("SELECT COUNT(*) as count FROM rooms", (err, row) => {
|
||||
@@ -279,6 +331,87 @@ adminBookingsModule.setupRoutes(app, authModule.authenticateToken, authModule.re
|
||||
promocodesModule.setupRoutes(app, authModule.authenticateToken, authModule.requireAdmin);
|
||||
roomsModule.setupRoutes(app);
|
||||
usersModule.setupRoutes(app, authModule.authenticateToken, authModule.requireAdmin);
|
||||
settingsModule.setupRoutes(app, authModule.authenticateToken, authModule.requireAdmin);
|
||||
reviewsModule.setupRoutes(app, authModule.authenticateToken, authModule.requireAdmin);
|
||||
|
||||
app.get('/api/translations/:lang', (req, res) => {
|
||||
const lang = req.params.lang;
|
||||
const translations = translationsModule.getTranslations(lang);
|
||||
if (!translations) {
|
||||
return res.status(404).json({ error: 'Language not found' });
|
||||
}
|
||||
res.json(translations);
|
||||
});
|
||||
|
||||
app.get('/api/countries-cities', (req, res) => {
|
||||
res.sendFile(path.join(__dirname, 'public', 'data', 'countries-cities.js'));
|
||||
});
|
||||
|
||||
app.get('/api/countries', (req, res) => {
|
||||
const countriesPath = path.join(__dirname, 'public', 'data', 'countries.js');
|
||||
fs.readFile(countriesPath, 'utf8', (err, data) => {
|
||||
if (err) return res.status(500).json({ error: 'File not found' });
|
||||
const match = data.match(/const\s+COUNTRIES\s*=\s*(\[.*\]);/s);
|
||||
if (match) {
|
||||
try {
|
||||
const countries = eval(match[1]);
|
||||
res.json(countries);
|
||||
} catch (e) {
|
||||
res.status(500).json({ error: 'Parse error' });
|
||||
}
|
||||
} else {
|
||||
res.status(500).json({ error: 'Parse error' });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/api/cities/:countryCode', (req, res) => {
|
||||
const countryCode = req.params.countryCode;
|
||||
|
||||
const citiesPath = path.join(__dirname, 'public', 'data', 'cities', `${countryCode}.js`);
|
||||
const majorCitiesPath = path.join(__dirname, 'public', 'data', 'cities', 'major.js');
|
||||
const filePath = fs.existsSync(citiesPath) ? citiesPath : (fs.existsSync(majorCitiesPath) ? majorCitiesPath : null);
|
||||
|
||||
if (!filePath) {
|
||||
return res.json({ cities: [], popular: [], countryCode });
|
||||
}
|
||||
|
||||
try {
|
||||
const data = fs.readFileSync(filePath, 'utf8');
|
||||
|
||||
let cities = [];
|
||||
const arrayMatch = data.match(/const\s+CITIES_\w+\s*=\s*(\[.*?\]);/s);
|
||||
if (arrayMatch) {
|
||||
cities = JSON.parse(arrayMatch[1].replace(/"/g, '"').replace(/'/g, "'"));
|
||||
}
|
||||
|
||||
if (cities.length === 0) {
|
||||
const majorMatch = data.match(/CITIES_BY_CODE\s*=\s*({[\s\S]*?});/);
|
||||
if (majorMatch) {
|
||||
const codeMatch = majorMatch[1].match(new RegExp(`${countryCode}:\\s*\\[([^\\]]+)\\]`));
|
||||
if (codeMatch) {
|
||||
cities = codeMatch[1].split(',').map(c => c.trim().replace(/^["']|["']$/g, ''));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cities.length === 0) {
|
||||
const defaultMatch = data.match(/CITIES_DEFAULT\s*=\s*(\[.*?\]);/s);
|
||||
if (defaultMatch) {
|
||||
try {
|
||||
const evalResult = eval(defaultMatch[1]);
|
||||
if (Array.isArray(evalResult)) {
|
||||
cities = evalResult;
|
||||
}
|
||||
} catch (e) {}
|
||||
}
|
||||
}
|
||||
|
||||
res.json({ cities, popular: [], countryCode });
|
||||
} catch (err) {
|
||||
res.status(500).json({ error: err.message });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.sendFile(path.join(__dirname, 'public', 'index.html'));
|
||||
|
||||
Reference in New Issue
Block a user