Skip to content

Commit

Permalink
Implement buyer able to leave feedback on products
Browse files Browse the repository at this point in the history
  • Loading branch information
UwicyezaG committed May 30, 2024
1 parent 5346a98 commit 6779fce
Show file tree
Hide file tree
Showing 10 changed files with 218 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/controllers/feedbackController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Request, Response } from 'express';
import { createFeedbackService } from '../services/feedbackServices/createFeedback';
import { updateFeedbackService } from '../services/feedbackServices/updateFeedback';
import { deleteFeedbackService } from '../services/feedbackServices/deleteFeedback';
import { getFeedbackService } from '../services/feedbackServices/getFeedback';
import { adminDeleteFeedbackService } from '../services/feedbackServices/adminDeleteFeedback';

export const createFeedback = async (req: Request, res: Response) => {
await createFeedbackService(req, res);
};

export const updateFeedback = async (req: Request, res: Response) => {
await updateFeedbackService(req, res);
};

export const deleteFeedback = async (req: Request, res: Response) => {
await deleteFeedbackService(req, res);
};

export const getFeedbacks = async (req: Request, res: Response) => {
await getFeedbackService(req, res);
};

export const adminDeleteFeedback = async (req: Request, res: Response) => {
await adminDeleteFeedbackService(req, res);
};
24 changes: 24 additions & 0 deletions src/entities/Feedback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Entity, PrimaryGeneratedColumn, Column, ManyToOne, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { User } from './User';
import { Product } from './Product';

@Entity()
export class Feedback {
@PrimaryGeneratedColumn()
id!: number;

@Column('text')
comment!: string;

@ManyToOne(() => User, user => user.feedbacks)
user!: User;

@ManyToOne(() => Product, product => product.feedbacks)
product!: Product;

@CreateDateColumn()
createdAt!: Date;

@UpdateDateColumn()
updatedAt!: Date;
}
1 change: 1 addition & 0 deletions src/entities/Product.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { VendorOrderItem } from './VendorOrderItem';
@Entity()
@Unique(['id'])
export class Product {
feedbacks: any;
static query () {
throw new Error('Method not implemented.');
}
Expand Down
2 changes: 2 additions & 0 deletions src/entities/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { IsEmail, IsNotEmpty, IsString, IsBoolean, IsIn } from 'class-validator'
import { roles } from '../utils/roles';
import { Order } from './Order';
import { Transaction } from './transaction';
import { Feedback } from './Feedback';

export interface UserInterface {
id?: string;
Expand Down Expand Up @@ -110,6 +111,7 @@ export class User {

@Column({ type: 'numeric', precision: 24, scale: 2, default: 0 })
accountBalance!: number;
feedbacks: any;

@BeforeInsert()
setRole (): void {
Expand Down
21 changes: 21 additions & 0 deletions src/routes/feedbackRoutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { RequestHandler, Router } from 'express';
import {
createFeedback,
updateFeedback,
deleteFeedback,
getFeedbacks,
adminDeleteFeedback
} from '../controllers/feedbackController'
import { authMiddleware } from '../middlewares/verifyToken';
import { hasRole } from '../middlewares/roleCheck';


const router = Router();

router.post('/products/:productId/feedback', authMiddleware as RequestHandler, hasRole('BUYER'), createFeedback);
router.put('/products/:productId/feedback/:feedbackId', authMiddleware as RequestHandler, hasRole('BUYER'), updateFeedback );
router.delete('/products/:productId/feedback/:feedbackId', authMiddleware as RequestHandler, hasRole('BUYER'), deleteFeedback);
router.get('/products/:productId/feedback', getFeedbacks );
router.delete('/admin/products/:productId/feedback/:feedbackId', authMiddleware as RequestHandler, hasRole('ADMIN'), adminDeleteFeedback );

export default router;
24 changes: 24 additions & 0 deletions src/services/feedbackServices/adminDeleteFeedback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Request, Response } from 'express';
import { getRepository } from 'typeorm';
import { Feedback } from '../../entities/Feedback';
import { responseError, responseSuccess } from '../../utils/response.utils';

export const adminDeleteFeedbackService = async (req: Request, res: Response) => {
const { feedbackId } = req.params;

try {
const feedbackRepository = getRepository(Feedback);
const feedback = await feedbackRepository.findOne({
where: { id: parseInt(feedbackId) } });

if (!feedback) {
return responseError(res, 404, 'Feedback not found');
}

await feedbackRepository.remove(feedback);

return responseSuccess(res, 200, 'Feedback deleted successfully by admin');
} catch (error) {
return responseError(res, 500, 'Server error');
}
};
41 changes: 41 additions & 0 deletions src/services/feedbackServices/createFeedback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Request, Response } from 'express';
import { getRepository } from 'typeorm';
import { Feedback } from '../../entities/Feedback';
import { Product } from '../../entities/Product';
import { User } from '../../entities/User';
import { responseError, responseSuccess } from '../../utils/response.utils';

interface AuthRequest extends Request {
user?: User;
}

export const createFeedbackService = async (req: Request, res: Response) => {
const { productId } = req.params;
const { comment } = req.body;

try {
const feedbackRepository = getRepository(Feedback);
const productRepository = getRepository(Product);

const product = await productRepository.findOne( {where : {id: productId} });
if (!product) {
return responseError(res, 404, 'Product not found');
}


if (!req.user) {
return responseError(res, 401, 'User not authenticated');
}

const feedback = new Feedback();
feedback.comment = comment;
feedback.user = req.user as User;
feedback.product = product;

await feedbackRepository.save(feedback);

return responseSuccess(res, 201, 'Feedback created successfully', feedback);
} catch (error) {
return responseError(res, 500, 'Server error');
}
};
28 changes: 28 additions & 0 deletions src/services/feedbackServices/deleteFeedback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Request, Response } from 'express';
import { getRepository } from 'typeorm';
import { Feedback } from '../../entities/Feedback';
import { responseError, responseSuccess } from '../../utils/response.utils';

export const deleteFeedbackService = async (req: Request, res: Response) => {
const { productId, feedbackId } = req.params;

try {
const feedbackRepository = getRepository(Feedback);
const feedback = await feedbackRepository.findOne({
where: { id: parseInt(feedbackId),
user: req.user,
product: { id: productId }
}
});

if (!feedback) {
return responseError(res, 404, 'Feedback not found');
}

await feedbackRepository.remove(feedback);

return responseSuccess(res, 200, 'Feedback deleted successfully');
} catch (error) {
return responseError(res, 500, 'Server error');
}
};
21 changes: 21 additions & 0 deletions src/services/feedbackServices/getFeedback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Request, Response } from 'express';
import { getRepository } from 'typeorm';
import { Feedback } from '../../entities/Feedback';
import { responseError, responseSuccess } from '../../utils/response.utils';

export const getFeedbackService = async (req: Request, res: Response) => {
const { productId } = req.params;

try {
const feedbackRepository = getRepository(Feedback);
const feedbacks = await feedbackRepository.find({ where: { product: { id: productId } }, relations: ['user'] });

if (!feedbacks.length) {
return responseError(res, 404, 'No feedback found for this product');
}

return responseSuccess(res, 200, 'Feedback retrieved successfully', feedbacks);
} catch (error) {
return responseError(res, 500, 'Server error');
}
};
30 changes: 30 additions & 0 deletions src/services/feedbackServices/updateFeedback.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { Request, Response } from 'express';
import { getRepository } from 'typeorm';
import { Feedback } from '../../entities/Feedback';
import { responseError, responseSuccess } from '../../utils/response.utils';

export const updateFeedbackService = async (req: Request, res: Response) => {
const { productId, feedbackId } = req.params;
const { comment } = req.body;

try {
const feedbackRepository = getRepository(Feedback);
const feedback = await feedbackRepository.findOne({
where: {
id: parseInt(feedbackId),
user: req.user,
product: { id: productId }}
});

if (!feedback) {
return responseError(res, 404, 'Feedback not found');
}

feedback.comment = comment;
await feedbackRepository.save(feedback);

return responseSuccess(res, 200, 'Feedback updated successfully', feedback);
} catch (error) {
return responseError(res, 500, 'Server error');
}
};

0 comments on commit 6779fce

Please sign in to comment.