Skip to content

Commit 8f045ac

Browse files
committed
Main calculation done
0 parents  commit 8f045ac

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+57221
-0
lines changed

.gitignore

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
node_modules
5+
node_modules/
6+
/.pnp
7+
.pnp.js
8+
9+
# testing
10+
/coverage
11+
12+
# production
13+
/frontend/build
14+
15+
# misc
16+
.DS_Store
17+
.env
18+
.env.local
19+
.env.development.local
20+
.env.test.local
21+
.env.production.local
22+
23+
npm-debug.log*
24+
yarn-debug.log*
25+
yarn-error.log*
26+
.vscode/settings.json

Procfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
web: node backend/server.js

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Booking-MERN Stack App Features
2+
3+
- Full featured shopping cart
4+
- Room reviews and ratings
5+
- Top Room carousel
6+
- Room pagination
7+
- Room search feature
8+
- User profile with orders
9+
- Admin Room management
10+
- Admin user management
11+
- Admin Order details page
12+
- Mark orders as delivered option
13+
- Checkout process (shipping, payment method, etc)
14+
- PayPal / credit card integration
15+
- Database seeder (Room & users)

backend/config/db.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import colors from 'colors'
2+
import mongoose from 'mongoose'
3+
4+
const connectDB = async () => {
5+
try {
6+
const conn = await mongoose.connect(process.env.MONGO_URI, {
7+
useUnifiedTopology: true,
8+
useNewUrlParser: true,
9+
})
10+
11+
console.log(colors.cyan.bold.underline(`Awesome MongoDB Connected: ${conn.connection.host}`))
12+
} catch (error) {
13+
console.error(`Error: ${error.message}`.red.underline.bold)
14+
process.exit(1)
15+
}
16+
}
17+
18+
export default connectDB
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import asyncHandler from 'express-async-handler'
2+
import Order from '../models/orderModel.js'
3+
4+
// @desc Create new order
5+
// @route POST /api/orders
6+
// @access Private
7+
8+
const addOrderItems = asyncHandler(async (req, res) => {
9+
const { orderItems, shippingAddress, paymentMethod, itemsPrice, taxPrice, shippingPrice, totalPrice } = req.body
10+
11+
if (orderItems && orderItems.length === 0) {
12+
res.status(400)
13+
throw new Error('No order items')
14+
return
15+
} else {
16+
const order = new Order({
17+
orderItems,
18+
user: req.user._id,
19+
shippingAddress,
20+
paymentMethod,
21+
itemsPrice,
22+
taxPrice,
23+
shippingPrice,
24+
totalPrice,
25+
})
26+
27+
const createdOrder = await order.save()
28+
29+
res.status(201).json(createdOrder)
30+
}
31+
})
32+
33+
// @desc Get order by ID
34+
// @route GET /api/orders/:id
35+
// @access Private
36+
37+
const getOrderById = asyncHandler(async (req, res) => {
38+
const order = await Order.findById(req.params.id).populate('user', 'name email')
39+
40+
if (order) {
41+
res.json(order)
42+
} else {
43+
res.status(404)
44+
throw new Error('Order not found')
45+
}
46+
})
47+
48+
// @desc Update order to paid
49+
// @route GET /api/orders/:id/pay
50+
// @access Private
51+
52+
const updateOrderToPaid = asyncHandler(async (req, res) => {
53+
const order = await Order.findById(req.params.id)
54+
55+
if (order) {
56+
order.isPaid = true
57+
order.paidAt = Date.now()
58+
order.paymentResult = {
59+
id: req.body.id,
60+
status: req.body.status,
61+
update_time: req.body.update_time,
62+
email_address: req.body.payer.email_address,
63+
}
64+
65+
const updatedOrder = await order.save()
66+
67+
res.json(updatedOrder)
68+
} else {
69+
res.status(404)
70+
throw new Error('Order not found')
71+
}
72+
})
73+
74+
// @desc Update order to delivered
75+
// @route GET /api/orders/:id/deliver
76+
// @access Private/Admin
77+
78+
const updateOrderToDelivered = asyncHandler(async (req, res) => {
79+
const order = await Order.findById(req.params.id)
80+
81+
if (order) {
82+
order.isDelivered = true
83+
order.deliveredAt = Date.now()
84+
85+
const updatedOrder = await order.save()
86+
87+
res.json(updatedOrder)
88+
} else {
89+
res.status(404)
90+
throw new Error('Order not found')
91+
}
92+
})
93+
94+
// @desc Get logged in user orders
95+
// @route GET /api/orders/myorders
96+
// @access Private
97+
98+
const getMyOrders = asyncHandler(async (req, res) => {
99+
const orders = await Order.find({ user: req.user._id })
100+
res.json(orders)
101+
})
102+
103+
// @desc Get all orders
104+
// @route GET /api/orders
105+
// @access Private/Admin
106+
107+
const getOrders = asyncHandler(async (req, res) => {
108+
const orders = await Order.find({}).populate('user', 'id name')
109+
res.json(orders)
110+
})
111+
112+
export { addOrderItems, getOrderById, updateOrderToPaid, updateOrderToDelivered, getMyOrders, getOrders }

backend/controllers/roomController.js

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
import asyncHandler from 'express-async-handler'
2+
import Room from '../models/roomModel.js'
3+
4+
// @desc Fetch all Rooms
5+
// @route GET /api/Rooms
6+
// @access Public
7+
8+
const getRooms = asyncHandler(async (req, res) => {
9+
const pageSize = 6
10+
const page = Number(req.query.pageNumber) || 1
11+
12+
const keyword = req.query.keyword ? { name: { $regex: req.query.keyword, $options: 'i' } } : {}
13+
14+
const count = await Room.countDocuments({ ...keyword })
15+
const rooms = await Room.find({ ...keyword })
16+
.limit(pageSize)
17+
.skip(pageSize * (page - 1))
18+
19+
res.json({ rooms, page, pages: Math.ceil(count / pageSize) })
20+
})
21+
22+
// @desc Fetch single Room
23+
// @route GET /api/Room/:id
24+
// @access Public
25+
26+
const getRoomById = asyncHandler(async (req, res) => {
27+
const room = await Room.findById(req.params.id)
28+
29+
if (room) {
30+
res.json(room)
31+
} else {
32+
res.status(404)
33+
throw new Error('Room not found')
34+
}
35+
})
36+
37+
// @desc Delete a room
38+
// @route DELETE /api/rooms/:id
39+
// @access Private/Admin
40+
41+
const deleteRoom = asyncHandler(async (req, res) => {
42+
const room = await Room.findById(req.params.id)
43+
44+
if (room) {
45+
await room.remove()
46+
res.json({ message: 'Room removed' })
47+
} else {
48+
res.status(404)
49+
throw new Error('Room not found')
50+
}
51+
})
52+
53+
// @desc Create a Room
54+
// @route POST /api/rooms
55+
// @access Private/Admin
56+
57+
const createRoom = asyncHandler(async (req, res) => {
58+
const room = new Room({
59+
name: 'Sample name',
60+
rentPerDay: 0,
61+
user: req.user._id,
62+
image: ['/images/sample0.jpg', '/images/sample1.jpg', '/images/sample2.jpg'],
63+
type: 'None Delux',
64+
phoneNumber: 0,
65+
countInStock: 0,
66+
numReviews: 0,
67+
description: 'Sample description',
68+
})
69+
70+
const createdRoom = await room.save()
71+
res.status(201).json(createdRoom)
72+
})
73+
74+
// @desc Update a Room
75+
// @route PUT /api/rooms/:id
76+
// @access Private/Admin
77+
78+
const updateRoom = asyncHandler(async (req, res) => {
79+
const { name, rentPerDay, description, image, type, phoneNumber, countInStock } = req.body
80+
81+
const room = await Room.findById(req.params.id)
82+
83+
if (room) {
84+
room.name = name
85+
room.rentPerDay = rentPerDay
86+
room.description = description
87+
room.image = image
88+
room.type = type
89+
room.phoneNumber = phoneNumber
90+
room.countInStock = countInStock
91+
const updatedRoom = await room.save()
92+
res.json(updatedRoom)
93+
} else {
94+
res.status(404)
95+
throw new Error('Room not found')
96+
}
97+
})
98+
99+
// @desc Create new review
100+
// @route POST /api/rooms/:id/reviews
101+
// @access Private
102+
103+
const createRoomReview = asyncHandler(async (req, res) => {
104+
const { rating, comment } = req.body
105+
106+
const room = await Room.findById(req.params.id)
107+
108+
if (room) {
109+
const alreadyReviewed = room.reviews.find((r) => r.user.toString() === req.user._id.toString())
110+
111+
if (alreadyReviewed) {
112+
res.status(400)
113+
throw new Error('Room already reviewed')
114+
}
115+
116+
const review = { name: req.user.name, rating: Number(rating), comment, user: req.user._id }
117+
118+
room.reviews.push(review)
119+
120+
room.numReviews = room.reviews.length
121+
122+
room.rating = room.reviews.reduce((acc, item) => item.rating + acc, 0) / room.reviews.length
123+
124+
await room.save()
125+
res.status(201).json({ message: 'Review added' })
126+
} else {
127+
res.status(404)
128+
throw new Error('Room not found')
129+
}
130+
})
131+
132+
// @desc Get top rated rooms
133+
// @route GET /api/rooms/top
134+
// @access Public
135+
136+
const getTopRooms = asyncHandler(async (req, res) => {
137+
const rooms = await Room.find({}).sort({ rating: -1 }).limit(3)
138+
139+
res.json(rooms)
140+
})
141+
142+
export { getRooms, getRoomById, deleteRoom, createRoom, updateRoom, createRoomReview, getTopRooms }

0 commit comments

Comments
 (0)