234 lines
4.8 KiB
JavaScript
234 lines
4.8 KiB
JavaScript
const { Review, User, Room, Booking } =
|
|
require('../databases/models');
|
|
const { Op } = require('sequelize');
|
|
|
|
/**
|
|
* Get reviews for a specific room
|
|
*/
|
|
const getRoomReviews = async (req, res, next) => {
|
|
try {
|
|
// Support both routes: /api/reviews/room/:roomId and /api/rooms/:id/reviews
|
|
const roomId = req.params.roomId || req.params.id;
|
|
|
|
if (!roomId) {
|
|
return res.status(400).json({
|
|
status: 'error',
|
|
message: 'roomId is required',
|
|
});
|
|
}
|
|
|
|
const reviews = await Review.findAll({
|
|
where: {
|
|
room_id: parseInt(roomId, 10),
|
|
status: 'approved',
|
|
},
|
|
include: [
|
|
{
|
|
model: User,
|
|
as: 'user',
|
|
attributes: ['id', 'full_name', 'email'],
|
|
},
|
|
],
|
|
order: [['created_at', 'DESC']],
|
|
});
|
|
|
|
res.status(200).json({
|
|
status: 'success',
|
|
data: {
|
|
reviews,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Create a new review (authenticated users only)
|
|
*/
|
|
const createReview = async (req, res, next) => {
|
|
try {
|
|
const { room_id, rating, comment } = req.body;
|
|
const userId = req.user.id;
|
|
|
|
// Check if room exists
|
|
const room = await Room.findByPk(room_id);
|
|
if (!room) {
|
|
return res.status(404).json({
|
|
status: 'error',
|
|
message: 'Room not found',
|
|
});
|
|
}
|
|
|
|
// Optional: Check if user has booked this room
|
|
// const hasBooked = await Booking.findOne({
|
|
// where: {
|
|
// user_id: userId,
|
|
// room_id: room_id,
|
|
// status: 'completed',
|
|
// },
|
|
// });
|
|
// if (!hasBooked) {
|
|
// return res.status(403).json({
|
|
// status: 'error',
|
|
// message: 'You can only review rooms you have booked',
|
|
// });
|
|
// }
|
|
|
|
// Check if user already reviewed this room
|
|
const existingReview = await Review.findOne({
|
|
where: {
|
|
user_id: userId,
|
|
room_id: room_id,
|
|
},
|
|
});
|
|
|
|
if (existingReview) {
|
|
return res.status(400).json({
|
|
status: 'error',
|
|
message: 'You have already reviewed this room',
|
|
});
|
|
}
|
|
|
|
// Create review
|
|
const review = await Review.create({
|
|
user_id: userId,
|
|
room_id,
|
|
rating,
|
|
comment,
|
|
status: 'pending', // Admin will approve
|
|
});
|
|
|
|
res.status(201).json({
|
|
status: 'success',
|
|
message: 'Review submitted successfully and is pending approval',
|
|
data: {
|
|
review,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Approve review (Admin only)
|
|
*/
|
|
const approveReview = async (req, res, next) => {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
const review = await Review.findByPk(id);
|
|
if (!review) {
|
|
return res.status(404).json({
|
|
status: 'error',
|
|
message: 'Review not found',
|
|
});
|
|
}
|
|
|
|
await review.update({ status: 'approved' });
|
|
|
|
res.status(200).json({
|
|
status: 'success',
|
|
message: 'Review approved successfully',
|
|
data: {
|
|
review,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Reject review (Admin only)
|
|
*/
|
|
const rejectReview = async (req, res, next) => {
|
|
try {
|
|
const { id } = req.params;
|
|
|
|
const review = await Review.findByPk(id);
|
|
if (!review) {
|
|
return res.status(404).json({
|
|
status: 'error',
|
|
message: 'Review not found',
|
|
});
|
|
}
|
|
|
|
await review.update({ status: 'rejected' });
|
|
|
|
res.status(200).json({
|
|
status: 'success',
|
|
message: 'Review rejected successfully',
|
|
data: {
|
|
review,
|
|
},
|
|
});
|
|
} catch (error) {
|
|
next(error);
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Get all reviews (Admin only)
|
|
*/
|
|
const getAllReviews = async (req, res, next) => {
|
|
try {
|
|
const {
|
|
status,
|
|
page = 1,
|
|
limit = 10,
|
|
} = req.query;
|
|
|
|
const whereClause = {};
|
|
if (status) {
|
|
whereClause.status = status;
|
|
}
|
|
|
|
const offset = (parseInt(page) - 1) * parseInt(limit);
|
|
|
|
const { count, rows: reviews } = await Review.findAndCountAll({
|
|
where: whereClause,
|
|
include: [
|
|
{
|
|
model: User,
|
|
as: 'user',
|
|
attributes: ['id', 'full_name', 'email', 'phone'],
|
|
},
|
|
{
|
|
model: Room,
|
|
as: 'room',
|
|
attributes: ['id', 'room_number'],
|
|
},
|
|
],
|
|
limit: parseInt(limit),
|
|
offset: offset,
|
|
order: [['created_at', 'DESC']],
|
|
});
|
|
|
|
res.status(200).json({
|
|
status: 'success',
|
|
data: {
|
|
reviews,
|
|
pagination: {
|
|
total: count,
|
|
page: parseInt(page),
|
|
limit: parseInt(limit),
|
|
totalPages: Math.ceil(count / parseInt(limit)),
|
|
},
|
|
},
|
|
});
|
|
} catch (error) {
|
|
console.error('Error in getAllReviews:', error);
|
|
next(error);
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
getRoomReviews,
|
|
createReview,
|
|
approveReview,
|
|
rejectReview,
|
|
getAllReviews,
|
|
};
|