Skip to content

Commit

Permalink
[finishes #187354260] Created feature that will allow sellers to upda…
Browse files Browse the repository at this point in the history
…te their products in stock

	modified:   src/controllers/productsController.ts
	modified:   src/helpers/claudinary.ts
	new file:   src/helpers/destroyImage.ts
	new file:   src/helpers/extractImageId.ts
	new file:   src/middlewares/handleFileUploads.ts
	modified:   src/routes/productRoutes.ts
  • Loading branch information
patrickhag committed May 16, 2024
1 parent 38f3a82 commit dc7bc15
Show file tree
Hide file tree
Showing 6 changed files with 123 additions and 9 deletions.
70 changes: 70 additions & 0 deletions src/controllers/productsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import sequelize from '../database/models';
import Notification from '../database/models/notification';
import User from '../database/models/user';
import { sendEmail } from '../helpers/send-email';
import { destroyImage } from '../helpers/destroyImage';
import { extractImageId } from '../helpers/extractImageId';

export const createProduct = async (req: Request, res: Response) => {
try {
Expand Down Expand Up @@ -70,6 +72,74 @@ export const createSize = async (req: Request, res: Response) => {
}
};

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

const data = {
name: req.body.name,
description: req.body.description,
colors: req.body.colors,
};

// update images
if (req.files) {
const product = await Product.findByPk(productId);
const foundImages = product?.images;

// delete already existing images
if (foundImages instanceof Array) {
for (let i = 0; i < foundImages.length; i++) {
const strImg = foundImages[i].toString();
const imageId = extractImageId(strImg) as string;
await destroyImage(imageId);
product!.images = [];
}
}

// update new images
const images: unknown = req.files;
const productImages = [];
if (images instanceof Array && images.length > 3) {
for (const image of images) {
const imageBuffer: Buffer = image.buffer;
const url = await uploadImage(imageBuffer);
productImages.push(url);
Product.update({ images: productImages }, { where: { id: productId } });
}
} else {
return res.status(400).json({
message: 'Product should have at least 4 images',
});
}
}
// update product
Product.update(data, { where: { id: productId } }).then(() => {
res.status(200).json({
ok: true,
message: 'Product updated successfully',
});
});
} catch (error) {
sendInternalErrorResponse(res, error);
}
};

// update size
export const updateSize = async (req: Request, res: Response) => {
try {
const { sizeId } = req.params;
const { size, price, discount, expiryDate } = req.body as SizeAttributes;
await Size.update({ size, price, discount, expiryDate }, { where: { id: sizeId } });
res.status(200).json({
ok: true,
message: 'Product size updated successfully',
});
} catch (error) {
sendInternalErrorResponse(res, error);
}
};

const checkSizeExistance = async (sizeId: string, res: Response) => {
const isSizeExist = await Size.findByPk(sizeId);

Expand Down
22 changes: 13 additions & 9 deletions src/helpers/claudinary.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { File } from 'buffer';
import { v2 as cloudinary } from 'cloudinary';
// const config = require("config");

cloudinary.config({
cloud_name: process.env.CLOUDINARY_NAME,
Expand All @@ -10,15 +10,19 @@ cloudinary.config({
const uploadImage = async (imageData: Buffer): Promise<string> => {
const base64Image = imageData.toString('base64');
return new Promise((resolve, reject) => {
cloudinary.uploader.upload(`data:image/png;base64,${base64Image}`, { public_id: 'user_image' }, (error, result) => {
if (error) {
reject(error);
} else {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const url: any = result?.secure_url;
resolve(url);
cloudinary.uploader.upload(
`data:image/png;base64,${base64Image}`,
{ public_id: String(Date.now()) },
(error, result) => {
if (error) {
reject(error);
} else {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const url: any = result?.secure_url;
resolve(url);
}
}
});
);
});
};
export default uploadImage;
11 changes: 11 additions & 0 deletions src/helpers/destroyImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { v2 as cloudinary } from 'cloudinary';

cloudinary.config({
cloud_name: process.env.CLOUDINARY_NAME,
api_key: process.env.CLOUDINARY_KEY,
api_secret: process.env.CLOUDINARY_SECRET,
});

export const destroyImage = async (public_id: string) => {
return await cloudinary.uploader.destroy(public_id);
};
10 changes: 10 additions & 0 deletions src/helpers/extractImageId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const extractImageId = (url: string) => {
const regex = /\/([a-zA-Z0-9]+)\.[a-z]+$/;
const match = url.match(regex);

if (match && match[1]) {
return match[1];
} else {
return null;
}
};
10 changes: 10 additions & 0 deletions src/middlewares/handleFileUploads.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { NextFunction, Request, Response } from 'express';
import multerUpload from '../helpers/multer';

export const handleFileUploads = (req: Request, res: Response, next: NextFunction) => {
if (req.files) {
multerUpload.array('images', 8)(req, res, next);
} else {
multerUpload.single('image')(req, res, next);
}
};
9 changes: 9 additions & 0 deletions src/routes/productRoutes.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-misused-promises */
import { Router } from 'express';
import {
createProduct,
Expand All @@ -7,6 +8,7 @@ import {
getProductById,
markProductAsAvailable,
markProductAsUnavailable,
updateProduct,
} from '../controllers/productsController';
import multerUpload from '../helpers/multer';
import { checkUserRoles, isAuthenticated } from '../middlewares/authMiddlewares';
Expand All @@ -21,6 +23,13 @@ router.post(
createProduct
);

router.put(
'/:productId/update-product',
multerUpload.array('images', 8),
isAuthenticated,
checkUserRoles('seller'),
updateProduct
);
router.post('/:productId/add-size', isAuthenticated, checkUserRoles('seller'), createSize);

router.get('/', getAllProduct);
Expand Down

0 comments on commit dc7bc15

Please sign in to comment.