const BlogTag = require('../models/blogTag'); // -------------------- Admin Controllers -------------------- // Display tag management page exports.index = async (req, res) => { try { const tags = await BlogTag.find() .sort({ name: 1 }) .lean(); res.render('admin/blog/tags/index', { layout: 'layouts/main', title: 'Blog Tags', tags, currentPath: req.path, user: req.session.user }); } catch (err) { console.error('Tag index error:', err); req.flash('error_msg', 'Error loading tags'); res.redirect('/admin/dashboard'); } }; // Show create tag form exports.create = async (req, res) => { try { res.render('admin/blog/tags/create', { layout: 'layouts/main', title: 'Create New Tag', currentPath: req.path, user: req.session.user }); } catch (err) { console.error('Tag create form error:', err); req.flash('error_msg', 'Error loading create form'); res.redirect('/admin/blog/tags'); } }; // Store new tag exports.store = async (req, res) => { try { const { name, isActive } = req.body; // Generate slug const slug = name .toLowerCase() .replace(/[^a-z0-9\s-]/g, '') .replace(/\s+/g, '-') .replace(/-+/g, '-') .trim('-'); // Check if slug exists const existingTag = await BlogTag.findOne({ slug }); if (existingTag) { req.flash('error_msg', 'A tag with this name already exists'); return res.redirect('/admin/blog/tags/create'); } // Create tag data const tagData = { name, slug, isActive: isActive === 'on' }; // Create tag const tag = new BlogTag(tagData); await tag.save(); req.flash('success_msg', 'Tag created successfully'); res.redirect('/admin/blog/tags'); } catch (err) { console.error('Tag store error:', err); req.flash('error_msg', 'Error creating tag'); res.redirect('/admin/blog/tags/create'); } }; // Show edit tag form exports.edit = async (req, res) => { try { const tag = await BlogTag.findById(req.params.id); if (!tag) { req.flash('error_msg', 'Tag not found'); return res.redirect('/admin/blog/tags'); } res.render('admin/blog/tags/edit', { layout: 'layouts/main', title: 'Edit Tag', tag, currentPath: req.path, user: req.session.user }); } catch (err) { console.error('Tag edit form error:', err); req.flash('error_msg', 'Error loading tag'); res.redirect('/admin/blog/tags'); } }; // Update tag exports.update = async (req, res) => { try { const tag = await BlogTag.findById(req.params.id); if (!tag) { req.flash('error_msg', 'Tag not found'); return res.redirect('/admin/blog/tags'); } const { name, isActive } = req.body; // Update tag data tag.name = name; tag.isActive = isActive === 'on'; // Generate new slug if name changed const newSlug = name .toLowerCase() .replace(/[^a-z0-9\s-]/g, '') .replace(/\s+/g, '-') .replace(/-+/g, '-') .trim('-'); if (newSlug !== tag.slug) { const existingTag = await BlogTag.findOne({ slug: newSlug, _id: { $ne: tag._id } }); if (existingTag) { req.flash('error_msg', 'A tag with this name already exists'); return res.redirect(`/admin/blog/tags/${tag._id}/edit`); } tag.slug = newSlug; } await tag.save(); req.flash('success_msg', 'Tag updated successfully'); res.redirect('/admin/blog/tags'); } catch (err) { console.error('Tag update error:', err); req.flash('error_msg', 'Error updating tag'); res.redirect(`/admin/blog/tags/${req.params.id}/edit`); } }; // Delete tag exports.destroy = async (req, res) => { try { const tag = await BlogTag.findById(req.params.id); if (!tag) { req.flash('error_msg', 'Tag not found'); return res.redirect('/admin/blog/tags'); } // Check if tag has posts const Blog = require('../models/blog'); const postCount = await Blog.countDocuments({ tags: { $in: [tag.name] } }); if (postCount > 0) { req.flash('error_msg', 'Cannot delete tag that is used in blog posts'); return res.redirect('/admin/blog/tags'); } await BlogTag.findByIdAndDelete(req.params.id); req.flash('success_msg', 'Tag deleted successfully'); res.redirect('/admin/blog/tags'); } catch (err) { console.error('Tag delete error:', err); req.flash('error_msg', 'Error deleting tag'); res.redirect('/admin/blog/tags'); } }; // -------------------- Public API Controllers -------------------- // Get all active tags exports.api = async (req, res) => { try { const tags = await BlogTag.getActive(); // Update post counts for (const tag of tags) { await tag.updatePostCount(); } res.json(tags); } catch (err) { console.error('Tags API error:', err); res.status(500).json({ error: 'Error loading tags' }); } }; // Get popular tags exports.apiPopular = async (req, res) => { try { const limit = parseInt(req.query.limit) || 10; const tags = await BlogTag.getPopular(limit); res.json(tags); } catch (err) { console.error('Popular tags API error:', err); res.status(500).json({ error: 'Error loading popular tags' }); } }; // Get tag by slug exports.apiShow = async (req, res) => { try { const tag = await BlogTag.findOne({ slug: req.params.slug, isActive: true }).lean(); if (!tag) { return res.status(404).json({ error: 'Tag not found' }); } res.json(tag); } catch (err) { console.error('Tag show API error:', err); res.status(500).json({ error: 'Error loading tag' }); } }; module.exports = exports;