houseofruqaapi / controllers /productController.js
ShieldX's picture
Upload 13 files
c0fb352 verified
// controllers/productController.js
import Product from '../models/Product.js';
// @desc Create a new product & upload images
// @route POST /api/products
export const createProduct = async (req, res) => {
try {
// 1. Extract text data from the request body
const { name, price, description, fabric, category, subcategory } = req.body;
// sizes might come as a stringified array or single string depending on FormData,
// so we parse it safely.
let sizesArray = [];
if (req.body.sizes) {
sizesArray = Array.isArray(req.body.sizes) ? req.body.sizes : req.body.sizes.split(',');
}
// 2. Extract uploaded image URLs from Cloudinary
// req.files is populated by our Multer/Cloudinary middleware
if (!req.files || req.files.length === 0) {
return res.status(400).json({ message: 'At least one image is required' });
}
const imageUrls = req.files.map((file) => file.path);
// 3. Create the product in MongoDB
const product = new Product({
name,
price: Number(price),
description,
fabric,
category,
subcategory,
sizes: sizesArray,
images: imageUrls,
});
const savedProduct = await product.save();
// 4. Send success response back to the frontend
res.status(201).json({
success: true,
message: 'Product added to House of Ruqa catalog successfully',
product: savedProduct
});
} catch (error) {
console.error('Error creating product:', error);
res.status(500).json({ success: false, message: 'Server Error', error: error.message });
}
};
// @desc Get all products (For the storefront grid)
// @route GET /api/products
export const getProducts = async (req, res) => {
try {
// Optional filtering (e.g., /api/products?category=Women)
const filter = req.query.category ? { category: req.query.category } : {};
// Fetch from DB, newest first
const products = await Product.find(filter).sort({ createdAt: -1 });
res.status(200).json({ success: true, count: products.length, products });
} catch (error) {
res.status(500).json({ success: false, message: 'Server Error' });
}
};
// @desc Get single product by ID
// @route GET /api/products/:id
export const getProductById = async (req, res) => {
try {
const product = await Product.findById(req.params.id);
if (product) {
res.status(200).json({ success: true, product });
} else {
res.status(404).json({ success: false, message: 'Product not found' });
}
} catch (error) {
res.status(500).json({ success: false, message: 'Server Error' });
}
};
// @desc Update a product
// @route PUT /api/products/:id
export const updateProduct = async (req, res) => {
try {
const { name, price, description, fabric, category, subcategory } = req.body;
let sizesArray = [];
if (req.body.sizes) {
sizesArray = Array.isArray(req.body.sizes) ? req.body.sizes : req.body.sizes.split(',').map(s => s.trim());
}
// Find product and update (Note: For MVP, we are updating text/details. Image updates require a more complex Cloudinary sync)
const updatedProduct = await Product.findByIdAndUpdate(
req.params.id,
{
name,
price: Number(price),
description,
fabric,
category,
subcategory,
sizes: sizesArray,
},
{ new: true, runValidators: true }
);
if (!updatedProduct) {
return res.status(404).json({ success: false, message: 'Product not found' });
}
res.status(200).json({ success: true, product: updatedProduct, message: 'Product updated successfully' });
} catch (error) {
res.status(500).json({ success: false, message: 'Server Error updating product' });
}
};
// @desc Delete a product
// @route DELETE /api/products/:id
export const deleteProduct = async (req, res) => {
try {
const product = await Product.findByIdAndDelete(req.params.id);
if (!product) {
return res.status(404).json({ success: false, message: 'Product not found' });
}
res.status(200).json({ success: true, message: 'Product deleted successfully' });
} catch (error) {
res.status(500).json({ success: false, message: 'Server Error deleting product' });
}
};