File size: 4,322 Bytes
c0fb352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
// 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' });
  }
};