const { prisma } = require('../../config/database'); exports.getAllCategories = async (req, res, next) => { try { const categories = await prisma.category.findMany({ orderBy: { name: 'asc' }, }); // res.json({ success: true, data: categories }); res.status(200).json({ // statusCode: 200, status: true, message: 'Categories fetched successfully', data: categories, }); } catch (error) { next(error); } }; exports.createCategory = async (req, res, next) => { try { const { name, description, image, parentId, metaTitle, metaDescription } = req.body; // Generate slug from name let slug = name .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/(^-|-$)/g, ''); // Check if slug already exists with the same parent const existing = await prisma.category.findFirst({ where: { slug, parentId: parentId || null, // Handle both subcategories and root categories }, }); if (existing) { // If exists under same parent, append timestamp to make it unique slug = `${slug}-${Date.now()}`; } const category = await prisma.category.create({ data: { name, slug, description, image, parentId, metaTitle, metaDescription, }, }); res.status(201).json({ statusCode: 201, status: true, message: 'Category created successfully', data: category, }); } catch (error) { // Handle Prisma duplicate error explicitly if (error.code === 'P2002') { return res.status(400).json({ statusCode: 400, status: false, message: 'Duplicate field value entered', }); } next(error); } }; exports.updateCategory = async (req, res, next) => { try { const { id } = req.params; const { name, description, image, parentId, metaTitle, metaDescription } = req.body; let slug; if (name) { slug = name .toLowerCase() .replace(/[^a-z0-9]+/g, '-') .replace(/(^-|-$)/g, ''); } const category = await prisma.category.update({ where: { id }, data: { name, slug, description, image, parentId, metaTitle, metaDescription, }, }); res.json({ status: true, message: 'Category updated successfully', data: category, }); } catch (error) { next(error); } }; exports.deleteCategory = async (req, res, next) => { try { const { id } = req.params; await prisma.category.delete({ where: { id }, }); res.json({ status: true, message: 'Category deleted successfully', }); } catch (error) { next(error); } }; exports.toggleCategoryStatus = async (req, res, next) => { try { const { id } = req.params; const { isActive } = req.body; // 1️⃣ Update parent category const parentCategory = await prisma.category.update({ where: { id }, data: { isActive }, }); // 2️⃣ If parent is being deactivated, also deactivate all children recursively if (!isActive) { const deactivateChildren = async parentId => { const children = await prisma.category.findMany({ where: { parentId }, }); for (const child of children) { await prisma.category.update({ where: { id: child.id }, data: { isActive: false }, }); // Recursive call for nested subcategories await deactivateChildren(child.id); } }; await deactivateChildren(id); } res.json({ status: true, message: `Category ${isActive ? 'activated' : 'deactivated'} successfully`, data: parentCategory, }); } catch (error) { next(error); } }; exports.reorderCategories = async (req, res) => { const { orders } = req.body; await Promise.all( orders.map(item => prisma.category.update({ where: { id: item.id }, data: { sequence: item.sequence }, }) ) ); res.json({ status: true, message: 'Category order updated', }); }; exports.getCategoryHierarchy = async (req, res, next) => { try { // 1. Fetch all categories const categories = await prisma.category.findMany({ orderBy: { name: 'asc' }, }); // 2. Convert array to a lookup map const lookup = {}; categories.forEach(cat => { lookup[cat.id] = { ...cat, children: [] }; }); const hierarchy = []; // 3. Build hierarchical structure categories.forEach(cat => { if (cat.parentId) { lookup[cat.parentId].children.push(lookup[cat.id]); } else { hierarchy.push(lookup[cat.id]); } }); res.status(200).json({ // statusCode: 200, status: true, message: 'Category hierarchy fetched successfully', data: hierarchy, }); } catch (error) { next(error); } }; exports.getCategoryById = async (req, res) => { try { const { id } = req.params; if (!id) { return res.status(400).json({ success: false, message: 'Category ID is required', }); } const category = await prisma.category.findUnique({ where: { id: id, // ✅ PASS THE ACTUAL STRING VALUE }, }); if (!category) { return res.status(404).json({ success: false, message: 'Category not found', }); } return res.status(200).json({ success: true, message: 'Category details fetched successfully', data: category, }); } catch (error) { console.error('Get category by id error:', error); return res.status(500).json({ success: false, message: 'Error fetching category', }); } };