diff --git a/client/src/pages/main/index.js b/client/src/pages/main/index.js
index ef8fcd8..2084e21 100644
--- a/client/src/pages/main/index.js
+++ b/client/src/pages/main/index.js
@@ -10,6 +10,7 @@ import Order from "./Order";
import UserInfo from "./UserInfo";
import Manager from "./Manager";
import SingleAuthor from "./SingleAuthor";
+import SingleOrder from "./SingleOrder";
export {
SharedLayout,
@@ -24,4 +25,5 @@ export {
Order,
UserInfo,
Manager,
+ SingleOrder,
}
\ No newline at end of file
diff --git a/client/src/utils/index.js b/client/src/utils/index.js
index a96482b..bc9f9a2 100644
--- a/client/src/utils/index.js
+++ b/client/src/utils/index.js
@@ -6,6 +6,47 @@ export const formatPrice = (price) => {
return VND
}
+export const formatVNTimeZoneDate = (datetime) => {
+ const dateUTC = datetime
+
+ // Chuyển đổi chuỗi thời gian thành đối tượng Date
+ const date = new Date(dateUTC)
+
+ // Định dạng lại thời gian theo múi giờ Việt Nam (GMT+7)
+ const options = {
+ timeZone: 'Asia/Ho_Chi_Minh', // Múi giờ Việt Nam
+ year: 'numeric',
+ month: '2-digit',
+ day: '2-digit',
+ hour: '2-digit',
+ minute: '2-digit',
+ second: '2-digit',
+ }
+
+
+ const formatter = new Intl.DateTimeFormat('vi-VN', options)
+ const dateInVietnamTime = formatter.format(date)
+
+ return dateInVietnamTime
+}
+
+export const ratingTitle = (rating) => {
+ switch(rating) {
+ case 1:
+ return 'Rất không hài lòng'
+ case 2:
+ return 'Không hài lòng'
+ case 3:
+ return 'Bình thường'
+ case 4:
+ return 'Hài lòng'
+ case 5:
+ return 'Cực kì hài lòng'
+ default:
+ return 'Chưa đánh giá'
+ }
+}
+
export const getCurrentDateTime = () => {
const now = new Date()
diff --git a/controllers/book.controller.js b/controllers/book.controller.js
index 5d1d4ee..3e6b39a 100644
--- a/controllers/book.controller.js
+++ b/controllers/book.controller.js
@@ -1,13 +1,10 @@
const { StatusCodes } = require('http-status-codes')
const { Op } = require('sequelize')
-const { Book, Category } = require('../models')
+const { Book, Category, Author, Publisher } = require('../models')
const Book_Info = require('../models/book_info.model')
-const Author = require('../models/author.model')
-const Publisher = require('../models/publisher.model')
const CustomAPIError = require('../errors/')
const asyncWrapper = require('../middleware/async')
const path = require('path')
-const crypto = require('crypto')
const cloudinary = require('cloudinary').v2
const fs = require('fs')
@@ -126,18 +123,18 @@ const deleteBook = asyncWrapper(async (req, res) => {
const uploadImage = async (req, res) => {
if (!req.files) {
- throw new CustomError.BadRequestError('No File Uploaded')
+ throw new CustomAPIError.BadRequestError('No File Uploaded')
}
const productImage = req.files.image
if (!productImage.mimetype.startsWith('image')) {
- throw new CustomError.BadRequestError('Please Upload Image')
+ throw new CustomAPIError.BadRequestError('Please Upload Image')
}
const maxSize = 1024 * 1024
if (productImage.size > maxSize) {
- throw new CustomError.BadRequestError(
+ throw new CustomAPIError.BadRequestError(
'Please upload image smaller than 1MB'
)
}
diff --git a/controllers/order.controller.js b/controllers/order.controller.js
index e37dbbc..0b58178 100644
--- a/controllers/order.controller.js
+++ b/controllers/order.controller.js
@@ -1,6 +1,5 @@
const Order = require('../models/order.model')
const Book = require('../models/book.model')
-const crypto = require('crypto')
const { v4: uuidv4 } = require('uuid')
const fetch = require('node-fetch')
@@ -79,8 +78,9 @@ const createPaypalOrder = async (cart) => {
subtotal += book.amount * price
}
// calculate total
- const total = tax + shipping_fee + subtotal
- if (total !== cart_total)
+ const total = tax + shipping_fee + subtotal
+
+ if (Math.ceil(total) !== Math.ceil(cart_total))
throw new CustomAPIError.BadRequestError(
'Have different in total price between client and server!'
)
@@ -107,7 +107,7 @@ const createPaypalOrder = async (cart) => {
reference_id: orderId,
amount: {
currency_code: 'USD',
- value: subtotal,
+ value: total,
},
},
],
@@ -159,7 +159,7 @@ const capturePaypalOrder = async (orderID, userId) => {
`No order with id : ${invoice?.purchase_units[0]?.reference_id}`
)
}
- order.status = 'paid'
+ order.is_paid = true
order.payment_intent_id = invoice?.purchase_units[0]?.payments?.captures?.id
await order.save()
return {
@@ -272,127 +272,6 @@ const createOrder = async (req, res) => {
.json({ order, clientSecret: order.clientSecret })
}
-// const createPaypalOrder = async (req, res) => {
-// const orderId = uuidv4()
-// const paypalRequestId = uuidv4()
-
-// const {
-// book_list,
-// tax,
-// shipping_fee,
-// cart_total,
-// customer_email,
-// shipping_address,
-// recipient_name,
-// recipient_phone,
-// payment_method,
-// client_id,
-// } = req.body
-
-// if (
-// !recipient_name ||
-// !customer_email ||
-// !recipient_phone ||
-// !shipping_address ||
-// !payment_method
-// ) {
-// throw new CustomAPIError.BadRequestError('Please provide customer details')
-// }
-
-// if (!book_list || book_list.length < 1) {
-// throw new CustomAPIError.BadRequestError('No cart items provided')
-// }
-
-// if (!tax || !shipping_fee || !cart_total) {
-// throw new CustomAPIError.BadRequestError(
-// 'Please provide tax and shipping fee and cart total'
-// )
-// }
-
-// let orderItems = []
-// let subtotal = 0
-// for (const book of book_list) {
-// const dbBook = await Book.findByPk(book.bookId)
-// if (!dbBook) {
-// throw new CustomAPIError.NotFoundError(`No book with id : ${book.bookId}`)
-// }
-// const { title, price, book_img, id } = dbBook
-// const singleOrderItem = {
-// amount: book.amount,
-// title,
-// price,
-// book_img,
-// bookID: id,
-// }
-// // add item to order
-// orderItems = [...orderItems, singleOrderItem]
-// // calculate subtotal
-// subtotal += book.amount * price
-// }
-// // calculate total
-// const total = tax + shipping_fee + subtotal
-// if (total !== cart_total)
-// throw new CustomAPIError.BadRequestError(
-// 'Have different in total price between client and server!'
-// )
-// // get client secret
-
-// const order = await Order.create({
-// id: orderId,
-// customer_email,
-// shipping_address,
-// recipient_name,
-// recipient_phone,
-// payment_method,
-// book_list: orderItems,
-// subtotal, // trị giá đơn hàng có tính phí ship và thuế
-// shipping_fee,
-// tax,
-// total,
-// user_id: req.user.userId,
-// })
-
-// const { id: paypalOrderId } = await fetch(
-// 'https://api-m.sandbox.paypal.com/v2/checkout/orders',
-// {
-// method: 'POST',
-// headers: {
-// 'Content-Type': 'application/json',
-// 'PayPal-Request-Id': paypalRequestId,
-// Authorization: `Basic ${client_id}`,
-// },
-// body: JSON.stringify({
-// intent: 'CAPTURE',
-// purchase_units: [
-// {
-// reference_id: orderId,
-// amount: { currency_code: 'USD', value: total },
-// item: orderItems,
-// },
-// ],
-// }),
-// }
-// )
-
-// return res.status(StatusCodes.CREATED).json({ order, paypalOrderId })
-
-// // const order = await Order.create({
-// // customer_name,
-// // customer_email,
-// // customer_phone,
-// // shipping_address,
-// // recipient_name,
-// // recipient_phone,
-// // payment_method,
-// // book_list: JSON.stringify(orderItems),
-// // subtotal, // trị giá đơn hàng có tính phí ship và thuế
-// // shipping_fee,
-// // tax,
-// // total,
-// // user_id: req.user.userId,
-// // client_secret: paymentIntent.client_secret,
-// // })
-// }
const getAllOrders = async (req, res) => {
const order = [['created_at', 'DESC']]
@@ -470,6 +349,22 @@ const updateOrder = async (req, res) => {
res.status(StatusCodes.OK).json({ order })
}
+const requestCancelOrder = async (req, res) => {
+ const { id: orderId } = req.params
+ checkPermissions(req.user, order.user_id)
+ const order = await Order.findByPk(orderId)
+ if (!order) {
+ throw new CustomAPIError.NotFoundError(`Không thể tìm được đơn hàng ${orderId}`)
+ }
+ if(order.status !== 'chờ xác nhận')
+ throw new CustomAPIError.BadRequestError(
+ `Đơn hàng đã được xác nhận. Vui lòng liên hệ nhân viên để xử lý!`
+ )
+ order.request_cancel = true
+ order.save()
+ res.status(StatusCodes.OK).json({ msg: 'Yêu cầu hủy đơn hàng đã được gửi!' })
+}
+
module.exports = {
getAllOrders,
getSingleOrder,
@@ -478,4 +373,5 @@ module.exports = {
createPaypalOrder,
updateOrder,
capturePaypalOrder,
+ requestCancelOrder,
}
diff --git a/controllers/order_item.controller.js b/controllers/order_item.controller.js
new file mode 100644
index 0000000..a09c0a0
--- /dev/null
+++ b/controllers/order_item.controller.js
@@ -0,0 +1,42 @@
+const { OrderItem } = require('../models')
+const CustomAPIError = require('../errors/')
+const asyncWrapper = require('../middleware/async')
+
+const findAllOrderItems = asyncWrapper(async (req, res) => {
+ const orderItems = await OrderItem.findAll()
+ res.status(200).json({ orderItems })
+})
+
+const findSingleOrderItem = asyncWrapper(async (req, res) => {
+ const { id } = req.params
+ const orderItem = await OrderItem.findByPk(id)
+ if (!orderItem)
+ throw new CustomAPIError.NotFoundError(`OrderItem ${id} not found`)
+ res.status(200).json({ orderItem })
+})
+
+const createOrderItem = asyncWrapper(async (req, res) => {
+ const { book_id, user_id } = req.body
+ const existingOrderItem = await OrderItem.findOne({
+ where: { book_id, user_id },
+ })
+ if(!existingOrderItem) {
+ const orderItem = await OrderItem.create({ ...req.body })
+ return res.status(201).json({ orderItem })
+ }
+ return
+})
+
+const deleteOrderItem = asyncWrapper(async (req, res) => {
+ const { id } = req.params
+ const orderItem = await OrderItem.findByPk(id)
+ await orderItem.destroy()
+ res.status(200).json({ msg: 'delete orderItem successfully' })
+})
+
+module.exports = {
+ findAllOrderItems,
+ findSingleOrderItem,
+ createOrderItem,
+ deleteOrderItem,
+}
diff --git a/controllers/review.controller.js b/controllers/review.controller.js
index efac306..9948e55 100644
--- a/controllers/review.controller.js
+++ b/controllers/review.controller.js
@@ -1,7 +1,8 @@
-const { Review, Book } = require('../models')
+const { Review, Book, OrderItem, User } = require('../models')
const CustomAPIError = require('../errors/')
const checkPermissions = require('../utils/checkPermissions')
const { StatusCodes } = require('http-status-codes')
+const sequelize = require('../dbconfig')
const createReview = async (req, res) => {
const { book_id } = req.body
@@ -25,9 +26,20 @@ const createReview = async (req, res) => {
throw new CustomAPIError.BadRequestError('Bạn đã đánh giá sách này rồi!')
}
+ const alreadyOrderedByUser = await OrderItem.findOne({
+ where: {
+ book_id,
+ user_id: req.user.userId,
+ },
+ })
+
+ if (!alreadyOrderedByUser) {
+ throw new CustomAPIError.BadRequestError('Bạn cần mua sản phẩm để đánh giá!')
+ }
+
req.body.user_id = req.user.userId
-
- const review = await Review.create({...req.body})
+
+ const review = await Review.create({ ...req.body })
res.status(StatusCodes.CREATED).json({ review })
}
@@ -94,9 +106,40 @@ const deleteReview = async (req, res) => {
res.status(StatusCodes.OK).json({ msg: 'Xóa đánh giá thành công' })
}
+const getCurrentUserReviewSingleBook = async (req, res) => {
+ const { id } = req.params
+ const key = process.env.ENCRYPTED_KEY
+ const review = await Review.findOne({
+ where: { book_id: id, user_id: req.user.userId },
+ include: {
+ model: User,
+ attributes: [
+ [sequelize.literal(`pgp_sym_decrypt("name", '${key}')`), 'name'],
+ 'user_img',
+ ],
+ },
+ })
+
+ if (review) {
+ return res.status(StatusCodes.OK).json({ review }) // trường hợp người dùng đã đánh giá
+ }
+ return res.status(StatusCodes.OK).json({ review: false }) // trường hợp người dùng chưa đánh giá
+}
+
const getSingleBookReviews = async (req, res) => {
const { id } = req.params
- const reviews = await Review.findOne({ book_id: id })
+ const key = process.env.ENCRYPTED_KEY
+ const reviews = await Review.findAll({
+ where: { book_id: id },
+ order: [['created_at', 'DESC']],
+ include: {
+ model: User,
+ attributes: [
+ [sequelize.literal(`pgp_sym_decrypt("name", '${key}')`), 'name'],
+ 'user_img',
+ ],
+ },
+ })
res.status(StatusCodes.OK).json({ reviews, count: reviews.length })
}
@@ -107,4 +150,5 @@ module.exports = {
updateReview,
deleteReview,
getSingleBookReviews,
+ getCurrentUserReviewSingleBook,
}
diff --git a/controllers/user.controller.js b/controllers/user.controller.js
index 29d9d21..194780b 100644
--- a/controllers/user.controller.js
+++ b/controllers/user.controller.js
@@ -29,7 +29,20 @@ const getSingleUser = async (req, res) => {
}
const showCurrentUser = async (req, res) => {
- res.status(StatusCodes.OK).json({ user: req.user })
+ const user = await User.findByPk(req.user.userId)
+ res
+ .status(StatusCodes.OK)
+ .json({
+ id: user.id,
+ name: user.name,
+ email: user.email,
+ phone_number: user.phone_number || "",
+ gender: user?.gender,
+ address: user?.address || "",
+ user_img: user?.user_img,
+ cccd: user?.cccd || "",
+
+ })
}
// update user with user.save()
const updateUser = asyncWrapper(async (req, res) => {
diff --git a/middleware/authentication.js b/middleware/authentication.js
index d43443a..7a1c7a4 100644
--- a/middleware/authentication.js
+++ b/middleware/authentication.js
@@ -7,8 +7,8 @@ const authenticateUser = async (req, res, next) => {
try {
// Kiểm tra access token có valid ko
if (accessToken) {
- payload = isTokenValid(accessToken)
- req.user = payload.user
+ const payload = isTokenValid(accessToken)
+ req.user = payload.user
return next()
}
// Kiểm tra refresh token có valid ko
@@ -31,7 +31,7 @@ const authenticateUser = async (req, res, next) => {
req.user = payload.user
next()
} catch (error) {
- throw new CustomError.UnauthenticatedError('Authentication Invalid')
+ throw new CustomError.UnauthenticatedError(error)
}
}
diff --git a/models/index.js b/models/index.js
index 6c7e3c0..a0b91f1 100644
--- a/models/index.js
+++ b/models/index.js
@@ -6,6 +6,7 @@ const User = require('./user.model')
const Publisher = require('./publisher.model')
const Token = require('./token.model')
const Review = require('./review.model')
+const OrderItem = require('./oder_item.model')
Author.hasMany(Book, { foreignKey: 'author_id' })
Book.belongsTo(Author, { foreignKey: 'author_id' })
@@ -25,6 +26,11 @@ Review.belongsTo(User, { foreignKey: 'user_id'})
Book.hasMany(Review, { foreignKey: 'book_id' })
Review.belongsTo(Book, { foreignKey: 'book_id' })
+User.hasMany(OrderItem, { foreignKey: 'user_id' })
+OrderItem.belongsTo(User, { foreignKey: 'user_id' })
+
+Book.hasMany(OrderItem, { foreignKey: 'book_id' })
+OrderItem.belongsTo(Book, { foreignKey: 'book_id' })
module.exports = {
Author,
@@ -35,4 +41,5 @@ module.exports = {
Publisher,
Token,
Review,
+ OrderItem,
}
diff --git a/models/oder_item.model.js b/models/oder_item.model.js
new file mode 100644
index 0000000..2c586ec
--- /dev/null
+++ b/models/oder_item.model.js
@@ -0,0 +1,32 @@
+const { Sequelize, DataTypes, Model } = require('sequelize')
+const sequelize = require('../dbconfig')
+
+class OderItem extends Model {}
+
+OderItem.init(
+ {
+ book_id: {
+ type: DataTypes.UUID,
+ references: {
+ model: 'book',
+ key: 'id',
+ }
+ },
+ user_id: {
+ type: DataTypes.UUID,
+ references: {
+ model: 'user',
+ key: 'id',
+ },
+ },
+ },
+ {
+ // Other model options go here
+ sequelize, // We need to pass the connection instance
+ modelName: 'order_item', // We need to choose the model name
+ tableName: 'order_items', // We need to choose the table name
+ timestamps: false,
+ }
+)
+
+module.exports = OderItem
diff --git a/models/order.model.js b/models/order.model.js
index de80959..773c362 100644
--- a/models/order.model.js
+++ b/models/order.model.js
@@ -1,6 +1,7 @@
const { Sequelize, DataTypes, Model } = require('sequelize')
const sequelize = require('../dbconfig')
const Book = require('./book.model')
+const OrderItem = require('./oder_item.model')
class Order extends Model {}
@@ -21,12 +22,7 @@ Order.init(
type: DataTypes.STRING(15),
},
payment_method: {
- type: DataTypes.ENUM(
- 'COD',
- 'Card',
- 'E-Wallet',
- 'Bank Transfer'
- ),
+ type: DataTypes.ENUM('COD', 'Card', 'E-Wallet', 'Bank Transfer'),
allowNull: false,
defaultValue: 'COD',
},
@@ -67,14 +63,15 @@ Order.init(
},
status: {
type: DataTypes.ENUM(
- 'pending',
- 'paid',
- 'failed',
- 'delivered',
- 'cancelled'
+ 'chờ xác nhận',
+ 'chờ lấy hàng',
+ 'đang vận chuyển',
+ 'đã giao',
+ 'đã hủy',
+ 'trả hàng'
),
allowNull: false,
- defaultValue: 'pending',
+ defaultValue: 'chờ xác nhận',
},
terms_accepted: {
type: DataTypes.BOOLEAN,
@@ -100,6 +97,16 @@ Order.init(
key: 'id',
},
},
+ is_paid: {
+ type: DataTypes.BOOLEAN,
+ allowNull: false,
+ defaultValue: false,
+ },
+ request_cancel: {
+ type: DataTypes.BOOLEAN,
+ allowNull: false,
+ defaultValue: false,
+ }
},
{
defaultScope: {
@@ -122,13 +129,26 @@ Order.init(
)
Order.afterUpdate(async (order, options) => {
- if (order.status === 'paid') {
+ if (order.status === 'đã giao') {
const bookList = order.book_list
for (const item of bookList) {
const book = await Book.findByPk(item.bookID)
if (book) {
- book.available_copies -= parseInt(item.amount)
- await book.save()
+ try {
+ book.available_copies -= parseInt(item.amount)
+ await book.save()
+ const orderItem = await OrderItem.findOne({
+ where: { user_id: order.user_id, book_id: book.id },
+ })
+ if (!orderItem) {
+ await OrderItem.create({
+ user_id: order.user_id,
+ book_id: book.id,
+ })
+ }
+ } catch (error) {
+ console.error(error)
+ }
}
}
}
diff --git a/models/review.model.js b/models/review.model.js
index 618e359..14c2262 100644
--- a/models/review.model.js
+++ b/models/review.model.js
@@ -15,17 +15,6 @@ Review.init(
notNull: { msg: 'Please provide rating' },
},
},
- title: {
- type: DataTypes.STRING,
- allowNull: false,
- validate: {
- notNull: { msg: 'Please provide review title' },
- len: {
- args: [0, 100],
- msg: 'Title must be less than or equal to 100 characters',
- },
- },
- },
comment: {
type: DataTypes.TEXT,
allowNull: false,
@@ -80,9 +69,7 @@ Review.calculateAverageRating = async function (book_id) {
raw: true,
})
- const averageRating = result[0].averageRating
- ? Math.ceil(result[0].averageRating)
- : 0
+ const averageRating = result[0].averageRating ? result[0].averageRating : 0
const numOfReviews = result[0].numOfReviews || 0
try {
diff --git a/routes/oder_item.router.js b/routes/oder_item.router.js
new file mode 100644
index 0000000..a300bda
--- /dev/null
+++ b/routes/oder_item.router.js
@@ -0,0 +1,26 @@
+const express = require('express')
+const router = express.Router()
+
+const {
+ authenticateUser,
+ authorizePermissions,
+} = require('../middleware/authentication')
+
+const {
+ findAllOrderItems,
+ findSingleOrderItem,
+ createOrderItem,
+ deleteOrderItem,
+} = require('../controllers/order_item.controller')
+
+router
+ .route('/')
+ .post(authenticateUser, createOrderItem)
+ .get(authenticateUser, authorizePermissions('admin'), findAllOrderItems)
+
+router
+ .route('/:id')
+ .get(findSingleOrderItem)
+ .delete(authenticateUser, authorizePermissions('admin'), deleteOrderItem)
+
+module.exports = router
diff --git a/routes/order.router.js b/routes/order.router.js
index b35ada6..e3d2413 100644
--- a/routes/order.router.js
+++ b/routes/order.router.js
@@ -13,6 +13,7 @@ const {
updateOrder,
createPaypalOrder,
capturePaypalOrder,
+ requestCancelOrder,
} = require('../controllers/order.controller')
router
@@ -20,6 +21,7 @@ router
.post(authenticateUser, createOrder)
.get(authenticateUser, authorizePermissions('admin'), getAllOrders)
+router.route('/requestCancelOrder').get(authenticateUser, requestCancelOrder)
router.route('/showAllMyOrders').get(authenticateUser, getCurrentUserOrders)
router.route('/paypal/createOrder').post(authenticateUser, async (req, res) => {
diff --git a/routes/review.router.js b/routes/review.router.js
index 7c0a923..2c67ebe 100644
--- a/routes/review.router.js
+++ b/routes/review.router.js
@@ -11,6 +11,8 @@ const {
getSingleReview,
updateReview,
deleteReview,
+ getSingleBookReviews,
+ getCurrentUserReviewSingleBook,
} = require('../controllers/review.controller')
router
@@ -18,6 +20,11 @@ router
.post(authenticateUser, authorizePermissions('user'), createReview)
.get(getAllReviews)
+router.route('/books/:id').get(getSingleBookReviews)
+router
+ .route('/getCurrentUserReviewSingleBook/:id')
+ .get(authenticateUser, getCurrentUserReviewSingleBook)
+
router
.route('/:id')
.get(getSingleReview)
diff --git a/server.js b/server.js
index 9a0a1fe..3c99cc9 100644
--- a/server.js
+++ b/server.js
@@ -26,6 +26,8 @@ const authRouter = require('./routes/auth.router')
const publisherRouter = require('./routes/publisher.router')
const orderRouter = require('./routes/order.router')
const reviewRouter = require('./routes/review.router')
+const orderItemRouter = require('./routes/oder_item.router')
+
// middleware
const notFoundMiddleware = require('./middleware/not-found')
@@ -72,6 +74,7 @@ app.use('/api/v1/auth', authRouter)
app.use('/api/v1/publishers', publisherRouter)
app.use('/api/v1/orders', orderRouter)
app.use('/api/v1/reviews', reviewRouter)
+app.use('/api/v1/orderItems', orderItemRouter)
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, './client/dist', 'index.html'))
diff --git a/utils/createTokenUser.js b/utils/createTokenUser.js
index 12c2c7b..db622e2 100644
--- a/utils/createTokenUser.js
+++ b/utils/createTokenUser.js
@@ -1,14 +1,8 @@
const createTokenUser = (user) => {
return {
name: user.name,
- email: user.email,
userId: user.id,
role: user.role,
- address: user.address,
- phoneNumber: user.phone_number,
- user_img: user.user_img,
- gender: user.gender,
- cccd: user.cccd
}
}
diff --git a/utils/index.js b/utils/index.js
index 25a11c4..f4330df 100644
--- a/utils/index.js
+++ b/utils/index.js
@@ -7,6 +7,15 @@ const hashString = require('./createHash')
const handleResponse = require('./handleResponse')
const generateAccessTokenPaypal = require('./generateAccessTokenPaypal')
const isValidCCCD = require('./checkIdCard')
+
+const formatPrice = (price) => {
+ const VND = new Intl.NumberFormat('vi-VN', {
+ style: 'currency',
+ currency: 'VND',
+ }).format((price * 1000).toFixed(2))
+ return VND
+}
+
module.exports = {
createJWT,
isTokenValid,
@@ -19,4 +28,5 @@ module.exports = {
handleResponse,
generateAccessTokenPaypal,
isValidCCCD,
+ formatPrice,
}
diff --git a/utils/jwt.js b/utils/jwt.js
index c01cfa2..2996861 100644
--- a/utils/jwt.js
+++ b/utils/jwt.js
@@ -11,7 +11,7 @@ const isTokenValid = (token) => jwt.verify(token, process.env.JWT_SECRET)
const attachCookiesToResponse = ({ res, user, refreshToken }) => {
//Tạo 2 token
- const accessTokenJWT = createJWT({ payload: user }) // dùng để truy cập vào secured resources
+ const accessTokenJWT = createJWT({ payload: { user } }) // dùng để truy cập vào secured resources
const refreshTokenJWT = createJWT({ payload: { user, refreshToken } }) //dùng để refresh access token
const oneDay = 1000 * 60 * 60 * 24