Team Ai
Apppublic

ctrlv-ince/gamezone-react-native

sourceHugging Facemitupdated 7mo agoView on Hugging Face
0likes
reviewController.js111 linesDownload Raw Back to controllers
1const { Product } = require('../models/product');2const { Order } = require('../models/order');3const mongoose = require('mongoose');4 5// Get reviews for a specific product6exports.getReviewsByProduct = async (req, res) => {7    try {8        const product = await Product.findById(req.params.productId)9            .select('reviews')10            .populate('reviews.user', 'name');11 12        if (!product) return res.status(404).json({ success: false, message: 'Product not found' });13 14        res.send(product.reviews);15    } catch (err) {16        res.status(500).json({ success: false, error: err.message });17    }18};19 20// User leaves a review21exports.createReview = async (req, res) => {22    try {23        const { user, product: productId, rating, comment, order: orderId } = req.body;24 25        // Verify purchased product26        const orders = await Order.find({ user: user, status: { $in: ['Shipped', 'Delivered'] } });27        if (!orders || orders.length === 0) {28            return res.status(403).send('You must have a verified purchase to leave a review.');29        }30 31        let hasPurchased = false;32        for (let order of orders) {33            for (let item of order.orderItems) {34                if (item.product.toString() === productId) {35                    hasPurchased = true;36                    break;37                }38            }39            if (hasPurchased) break;40        }41 42        if (!hasPurchased) {43            return res.status(403).send('You did not purchase this product or it has not been delivered.');44        }45 46        const product = await Product.findById(productId);47        if (!product) return res.status(404).send('Product not found');48 49        // Check if user already reviewed this product50        const existingReview = product.reviews.find(r => r.user.toString() === user);51        if (existingReview) {52            return res.status(400).send('You have already reviewed this product. You can update it instead.');53        }54 55        // Add review as embedded subdocument56        product.reviews.push({57            user,58            name: req.body.name || 'User',59            rating,60            comment,61            order: orderId,62        });63 64        // Update product average rating65        product.numReviews = product.reviews.length;66        product.rating = product.reviews.reduce((acc, r) => acc + r.rating, 0) / product.reviews.length;67 68        await product.save();69 70        // Mark isReviewed on the order item71        if (orderId) {72            await Order.updateOne(73                { _id: orderId, 'orderItems.product': productId },74                { $set: { 'orderItems.$.isReviewed': true } }75            );76        }77 78        res.send(product.reviews[product.reviews.length - 1]);79    } catch (err) {80        res.status(500).json({ success: false, error: err.message });81    }82};83 84// User updates their own review85exports.updateReview = async (req, res) => {86    try {87        const product = await Product.findOne({ 'reviews._id': req.params.id });88        if (!product) return res.status(404).send('Review not found');89 90        const review = product.reviews.id(req.params.id);91        if (!review) return res.status(404).send('Review not found');92 93        // Verify ownership94        if (review.user.toString() !== req.body.user) {95            return res.status(403).send('You can only update your own review');96        }97 98        review.rating = req.body.rating;99        review.comment = req.body.comment;100 101        // Recalculate average rating102        product.rating = product.reviews.reduce((acc, r) => acc + r.rating, 0) / product.reviews.length;103 104        await product.save();105 106        res.send(review);107    } catch (err) {108        res.status(500).json({ success: false, error: err.message });109    }110};111