206 lines
7.0 KiB
JavaScript
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 };
|