Files
kalugin66 38117f003d
All checks were successful
Deploy hotel / deploy-kdo (push) Successful in 34s
фикс
2026-07-19 00:42:39 +05:00

206 lines
7.0 KiB
JavaScript

const path = require('path');
const fs = require('fs');
let db;
function init(database) {
db = database;
}
function getUploadsDir() {
const dir = path.join(__dirname, '..', '..', 'data', 'activity_images');
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
return dir;
}
function validLangCount(row) {
let count = 0;
if (row.title_ru || row.desc_ru) count++;
if (row.title_en || row.desc_en) count++;
if (row.title_ab || row.desc_ab) count++;
return count;
}
function pickLang(row, lang) {
const filled = validLangCount(row);
if (filled === 1) {
if (row.title_ru || row.desc_ru) return { title: row.title_ru, desc: row.desc_ru };
if (row.title_en || row.desc_en) return { title: row.title_en, desc: row.desc_en };
return { title: row.title_ab, desc: row.desc_ab };
}
return {
title: row['title_' + lang] || row.title_ru || '',
desc: row['desc_' + lang] || row.desc_ru || ''
};
}
function getPublicActivities(req, res) {
const lang = req.query.lang || 'ru';
db.all(
`SELECT id, title_ru, title_en, title_ab, desc_ru, desc_en, desc_ab, icon, image_path
FROM activities WHERE is_active = 1 ORDER BY sort_order ASC, id ASC`,
[],
(err, rows) => {
if (err) {
console.error('Get activities error:', err);
return res.status(500).json({ error: 'Database error' });
}
const activities = rows.map(row => {
const localized = pickLang(row, lang);
return {
id: row.id,
title: localized.title,
desc: localized.desc,
icon: row.icon,
image_path: row.image_path
};
});
res.json(activities);
}
);
}
function getAdminActivities(req, res) {
db.all(
`SELECT * FROM activities ORDER BY sort_order ASC, id ASC`,
[],
(err, rows) => {
if (err) {
console.error('Get admin activities error:', err);
return res.status(500).json({ error: 'Database error' });
}
rows.forEach(row => {
row.created_at = row.created_at ? new Date(row.created_at).toISOString() : null;
});
res.json(rows);
}
);
}
function createActivity(req, res) {
const { title_ru, title_en, title_ab, desc_ru, desc_en, desc_ab, icon, image_path, sort_order } = req.body;
const rawRow = { title_ru, title_en, title_ab, desc_ru, desc_en, desc_ab };
const count = validLangCount(rawRow);
if (count !== 1 && count !== 3) {
return res.status(400).json({ error: 'Должен быть заполнен 1 язык или все 3' });
}
db.run(
`INSERT INTO activities (title_ru, title_en, title_ab, desc_ru, desc_en, desc_ab, icon, image_path, sort_order, is_active)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 1)`,
[title_ru || null, title_en || null, title_ab || null, desc_ru || null, desc_en || null, desc_ab || null, icon || null, image_path || null, sort_order || 0],
function(err) {
if (err) {
console.error('Create activity error:', err);
return res.status(500).json({ error: 'Database error' });
}
res.status(201).json({ message: 'Activity created', id: this.lastID });
}
);
}
function updateActivity(req, res) {
const id = parseInt(req.params.id);
const langFields = ['title_ru', 'title_en', 'title_ab', 'desc_ru', 'desc_en', 'desc_ab'];
const anyLangChanged = langFields.some(f => req.body[f] !== undefined);
if (anyLangChanged) {
const rawRow = {};
langFields.forEach(f => { rawRow[f] = req.body[f]; });
const count = validLangCount(rawRow);
if (count !== 0 && count !== 1 && count !== 3) {
return res.status(400).json({ error: 'Должен быть заполнен 1 язык или все 3' });
}
}
const allowed = ['title_ru', 'title_en', 'title_ab', 'desc_ru', 'desc_en', 'desc_ab', 'icon', 'image_path', 'sort_order', 'is_active'];
const fields = [];
const values = [];
allowed.forEach(f => {
if (req.body[f] !== undefined) {
fields.push(f + ' = ?');
values.push(req.body[f] === '' ? null : req.body[f]);
}
});
if (!fields.length) {
return res.status(400).json({ error: 'No fields to update' });
}
values.push(id);
db.run(
`UPDATE activities SET ${fields.join(', ')} WHERE id = ?`,
values,
function(err) {
if (err) {
console.error('Update activity error:', err);
return res.status(500).json({ error: 'Database error' });
}
if (this.changes === 0) {
return res.status(404).json({ error: 'Activity not found' });
}
res.json({ message: 'Activity updated', id });
}
);
}
function deleteActivity(req, res) {
const id = parseInt(req.params.id);
db.run(`DELETE FROM activities WHERE id = ?`, [id], function(err) {
if (err) {
console.error('Delete activity error:', err);
return res.status(500).json({ error: 'Database error' });
}
if (this.changes === 0) {
return res.status(404).json({ error: 'Activity not found' });
}
res.json({ message: 'Activity deleted', id });
});
}
function uploadActivityImage(req, res) {
if (!req.file) {
return res.status(400).json({ error: 'No file uploaded' });
}
const filename = req.file.filename;
const activityId = parseInt(req.params.id);
const imagePath = 'data/activity_images/' + filename;
if (activityId && req.body.update_activity === '1') {
db.run(`UPDATE activities SET image_path = ? WHERE id = ?`, [imagePath, activityId], function(err) {
if (err) {
console.error('Update activity image error:', err);
return res.status(500).json({ error: 'Database error' });
}
});
}
res.json({ message: 'Image uploaded', path: imagePath, filename });
}
function getAllActivities(req, res) {
getAdminActivities(req, res);
}
function setupRoutes(app, authenticateToken, requireAdmin, upload) {
app.get('/api/activities', getPublicActivities);
app.get('/api/admin/activities', authenticateToken, getAllActivities);
app.post('/api/admin/activities', authenticateToken, createActivity);
app.put('/api/admin/activities/:id', authenticateToken, updateActivity);
app.delete('/api/admin/activities/:id', authenticateToken, deleteActivity);
app.post('/api/admin/activities/upload', authenticateToken, upload.single('image'), uploadActivityImage);
app.post('/api/admin/activities/:id/image', authenticateToken, upload.single('image'), uploadActivityImage);
}
module.exports = { init, setupRoutes, getUploadsDir };