11import { Request , Response } from 'express' ;
22import { db } from '../database/models' ;
3- import { where } from 'sequelize' ;
43import validateProductReview from '../validations/validateProductReview' ;
54
65interface User {
@@ -10,81 +9,105 @@ interface User {
109interface CustomRequest extends Request {
1110 user ?: User ;
1211}
12+
1313interface Review {
1414 reviewComment : string ;
1515 rating : number ;
16+ User : {
17+ firstName : string ;
18+ lastName : string ;
19+ } ;
1620}
1721
1822export default class ProductReviewController {
19- static async Review ( req : CustomRequest , res : Response ) {
20- validateProductReview ( req . body as Review ) ;
21- const user = ( req as any ) . user ;
22- try {
23- const foundUser = await db . User . findOne ( {
24- where : { userId : user . userId } ,
25- } ) ;
23+ static async createReview ( req : CustomRequest , res : Response ) {
24+ const { reviewComment, rating } = req . body ;
25+ const userId = req . user ?. userId ;
26+ const productId = req . params . id ;
2627
28+ if ( ! userId || ! productId ) {
29+ return res . status ( 400 ) . json ( { message : 'Missing user or product ID' } ) ;
30+ }
31+
32+ try {
33+ const foundUser = await db . User . findOne ( { where : { userId } } ) ;
2734 if ( ! foundUser ) {
28- return res . status ( 404 ) . json ( {
29- message : 'user with the given Id is not found' ,
30- } ) ;
35+ return res . status ( 404 ) . json ( { message : 'User not found' } ) ;
3136 }
32- const foundProduct = await db . Product . findOne ( {
33- where : { productId : req . params . id } ,
34- } ) ;
37+
38+ const foundProduct = await db . Product . findOne ( { where : { productId } } ) ;
3539 if ( ! foundProduct ) {
36- return res . status ( 404 ) . json ( {
37- message : 'product with the given id not found' ,
38- } ) ;
40+ return res . status ( 404 ) . json ( { message : 'Product not found' } ) ;
3941 }
40- const AlreadyReviewed = await db . ProductReview . findOne ( {
41- where : { userId : foundUser . userId } ,
42+
43+ let review = await db . ProductReview . findOne ( {
44+ where : { userId, productId } ,
4245 } ) ;
43- if ( AlreadyReviewed ) {
44- return res . status ( 401 ) . json ( {
45- message : 'you can review a product only once' ,
46+
47+ if ( review ) {
48+ // Review exists, update it
49+ if ( reviewComment !== undefined ) review . reviewComment = reviewComment ;
50+ if ( rating !== undefined ) review . rating = rating ;
51+ await review . save ( ) ;
52+ } else {
53+ // Create new review
54+ review = await db . ProductReview . create ( {
55+ productId,
56+ userId,
57+ reviewComment : reviewComment || null , // Set to null if not provided
58+ rating : rating || null , // Set to null if not provided
4659 } ) ;
4760 }
48- const ProductReview = await db . ProductReview . create ( {
49- productId : req . params . id ,
50- userId : foundUser . userId ,
51- reviewComment : req . body . reviewComment ,
52- rating : req . body . rating ,
53- } ) ;
61+
5462 return res . status ( 200 ) . json ( {
55- message : 'review recorded successfully' ,
63+ message : 'Review processed successfully' ,
64+ review,
65+ user : {
66+ firstName : foundUser . firstName ,
67+ lastName : foundUser . lastName ,
68+ } ,
5669 } ) ;
57- } catch ( error : any ) {
70+ } catch ( error ) {
5871 return res . status ( 500 ) . json ( {
59- message : error . message ,
72+ message :
73+ error instanceof Error ? error . message : 'An unknown error occurred' ,
6074 } ) ;
6175 }
6276 }
6377
6478 static async editReview ( req : CustomRequest , res : Response ) {
6579 validateProductReview ( req . body as Review ) ;
66- const user = ( req as any ) . user ;
80+ const user = req . user ;
81+ if ( ! user ) {
82+ return res . status ( 400 ) . json ( { message : 'User information is missing' } ) ;
83+ }
6784 try {
6885 const foundUser = await db . User . findOne ( {
6986 where : { userId : user . userId } ,
7087 } ) ;
7188 if ( ! foundUser ) {
7289 return res . status ( 404 ) . json ( {
73- message : 'user with the given id not found' ,
90+ message : 'User with the given id not found' ,
7491 } ) ;
7592 }
7693 let foundReview = await db . ProductReview . findOne ( {
7794 where : { userId : foundUser . userId , productId : req . params . id } ,
7895 } ) ;
7996 if ( ! foundReview ) {
8097 return res . status ( 404 ) . json ( {
81- message : 'review not found for the given product by the user' ,
98+ message : 'Review not found for the given product by the user' ,
8299 } ) ;
83100 }
84- foundReview = await foundReview . update ( {
85- rating : req . body . rating ,
86- reviewComment : req . body . reviewComment ,
87- } ) ;
101+ // Update reviewComment if provided
102+ if ( req . body . reviewComment !== undefined ) {
103+ foundReview . reviewComment = req . body . reviewComment ;
104+ }
105+ // Update rating if provided
106+ if ( req . body . rating !== undefined ) {
107+ foundReview . rating = req . body . rating ;
108+ }
109+ await foundReview . save ( ) ;
110+
88111 return res . status ( 200 ) . json ( {
89112 message : 'Review updated successfully' ,
90113 review : foundReview ,
@@ -97,22 +120,25 @@ export default class ProductReviewController {
97120 }
98121
99122 static async deleteReview ( req : CustomRequest , res : Response ) {
100- const user = ( req as any ) . user ;
123+ const user = req . user ;
124+ if ( ! user ) {
125+ return res . status ( 400 ) . json ( { message : 'User information is missing' } ) ;
126+ }
101127 try {
102128 const foundUser = await db . User . findOne ( {
103129 where : { userId : user . userId } ,
104130 } ) ;
105131 if ( ! foundUser ) {
106132 return res . status ( 404 ) . json ( {
107- message : 'user with the given id not found' ,
133+ message : 'User with the given id not found' ,
108134 } ) ;
109135 }
110136 const foundReview = await db . ProductReview . findOne ( {
111137 where : { userId : foundUser . userId , productId : req . params . id } ,
112138 } ) ;
113139 if ( ! foundReview ) {
114140 return res . status ( 404 ) . json ( {
115- message : 'review not found for the given product by the user' ,
141+ message : 'Review not found for the given product by the user' ,
116142 } ) ;
117143 }
118144 await foundReview . destroy ( ) ;
@@ -133,7 +159,7 @@ export default class ProductReviewController {
133159 } ) ;
134160 if ( ! foundProduct ) {
135161 return res . status ( 404 ) . json ( {
136- message : 'product with the given id not found' ,
162+ message : 'Product with the given id not found' ,
137163 } ) ;
138164 }
139165 await db . ProductReview . destroy ( {
@@ -150,24 +176,49 @@ export default class ProductReviewController {
150176 }
151177
152178 static async getAllReviews ( req : CustomRequest , res : Response ) {
179+ const productId = req . params . id ;
180+
153181 try {
154182 const foundProduct = await db . Product . findOne ( {
155- where : { productId : req . params . id } ,
183+ where : { productId } ,
156184 } ) ;
157- if ( ! foundProduct )
185+
186+ if ( ! foundProduct ) {
158187 return res . status ( 404 ) . json ( {
159188 message : 'Product with the given id not found' ,
160189 } ) ;
190+ }
191+
161192 const reviews = await db . ProductReview . findAll ( {
162- where : { productId : foundProduct . productId } ,
193+ where : { productId } ,
194+ include : [
195+ {
196+ model : db . User ,
197+ attributes : [ 'firstName' , 'lastName' ] , // Only include firstName and lastName
198+ } ,
199+ ] ,
200+ attributes : [ 'reviewComment' , 'rating' , 'userId' ] , // Include any other attributes you need
163201 } ) ;
164- if ( reviews . length === 0 )
202+
203+ if ( reviews . length === 0 ) {
165204 return res . status ( 404 ) . json ( {
166- message : 'this product has no reviews' ,
205+ message : 'This product has no reviews' ,
167206 } ) ;
207+ }
208+
209+ // Format the response to include user details
210+ const formattedReviews = reviews . map ( ( review : Review ) => ( {
211+ reviewComment : review . reviewComment ,
212+ rating : review . rating ,
213+ user : {
214+ firstName : review . User . firstName ,
215+ lastName : review . User . lastName ,
216+ } ,
217+ } ) ) ;
218+
168219 return res . status ( 200 ) . json ( {
169- message : 'reviews retrieved successfully' ,
170- data : reviews ,
220+ message : 'Reviews retrieved successfully' ,
221+ data : formattedReviews ,
171222 } ) ;
172223 } catch ( error ) {
173224 return res . status ( 500 ) . json ( {
0 commit comments