const express = require('express'); const router = express.Router(); const Portfolio = require('../models/Portfolio'); // Get all portfolio items router.get('/', async (req, res) => { try { const page = parseInt(req.query.page) || 1; const limit = parseInt(req.query.limit) || 12; const skip = (page - 1) * limit; const category = req.query.category; const search = req.query.search; const featured = req.query.featured; // Build query let query = { isPublished: true }; if (category && category !== 'all') { query.category = category; } if (featured === 'true') { query.featured = true; } if (search) { query.$text = { $search: search }; } // Get portfolio items const [portfolio, total] = await Promise.all([ Portfolio.find(query) .sort({ featured: -1, publishedAt: -1 }) .skip(skip) .limit(limit) .select('title shortDescription category technologies images status publishedAt viewCount'), Portfolio.countDocuments(query) ]); const totalPages = Math.ceil(total / limit); res.json({ success: true, portfolio, pagination: { current: page, total: totalPages, limit, totalItems: total, hasNext: page < totalPages, hasPrev: page > 1 } }); } catch (error) { console.error('Portfolio API error:', error); res.status(500).json({ success: false, message: 'Error fetching portfolio' }); } }); // Get single portfolio item router.get('/:id', async (req, res) => { try { const portfolio = await Portfolio.findById(req.params.id); if (!portfolio || !portfolio.isPublished) { return res.status(404).json({ success: false, message: 'Portfolio item not found' }); } // Increment view count portfolio.viewCount += 1; await portfolio.save(); // Get related projects const relatedProjects = await Portfolio.find({ _id: { $ne: portfolio._id }, category: portfolio.category, isPublished: true }) .select('title shortDescription images') .limit(4); res.json({ success: true, portfolio, relatedProjects }); } catch (error) { console.error('Portfolio detail API error:', error); res.status(500).json({ success: false, message: 'Error fetching portfolio item' }); } }); // Get portfolio categories router.get('/meta/categories', async (req, res) => { try { const categories = await Portfolio.distinct('category', { isPublished: true }); // Get count for each category const categoriesWithCount = await Promise.all( categories.map(async (category) => { const count = await Portfolio.countDocuments({ category, isPublished: true }); return { category, count }; }) ); res.json({ success: true, categories: categoriesWithCount }); } catch (error) { console.error('Portfolio categories API error:', error); res.status(500).json({ success: false, message: 'Error fetching categories' }); } }); // Like portfolio item router.post('/:id/like', async (req, res) => { try { const portfolio = await Portfolio.findById(req.params.id); if (!portfolio || !portfolio.isPublished) { return res.status(404).json({ success: false, message: 'Portfolio item not found' }); } portfolio.likes += 1; await portfolio.save(); res.json({ success: true, likes: portfolio.likes }); } catch (error) { console.error('Portfolio like API error:', error); res.status(500).json({ success: false, message: 'Error liking portfolio item' }); } }); // Search portfolio router.get('/search/:term', async (req, res) => { try { const searchTerm = req.params.term; const limit = parseInt(req.query.limit) || 10; const portfolio = await Portfolio.find({ $and: [ { isPublished: true }, { $or: [ { title: { $regex: searchTerm, $options: 'i' } }, { description: { $regex: searchTerm, $options: 'i' } }, { technologies: { $in: [new RegExp(searchTerm, 'i')] } } ] } ] }) .select('title shortDescription category images') .sort({ featured: -1, publishedAt: -1 }) .limit(limit); res.json({ success: true, portfolio, searchTerm, count: portfolio.length }); } catch (error) { console.error('Portfolio search API error:', error); res.status(500).json({ success: false, message: 'Error searching portfolio' }); } }); module.exports = router;