Skip to content

Commit 8ab299a

Browse files
committed
End of Section 4: Getting Started With MongoDB
1 parent 1fb78fc commit 8ab299a

File tree

12 files changed

+574
-20
lines changed

12 files changed

+574
-20
lines changed

backend/config/db.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import mongoose from 'mongoose'
2+
3+
const connectDB = async () => {
4+
try {
5+
const conn = await mongoose.connect(process.env.MONGO_URI, {
6+
useUnifiedTopology: true,
7+
useNewUrlParser: true,
8+
useCreateIndex: true,
9+
})
10+
11+
console.log(`MongoDB Connected: ${conn.connection.host}`.cyan.underline)
12+
} catch (error) {
13+
console.error(`Error: ${error.message}`.red.underline.bold)
14+
process.exit(1)
15+
}
16+
}
17+
18+
export default connectDB

backend/data/products.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const products = [
22
{
3-
_id: '1',
43
name: 'Airpods Wireless Bluetooth Headphones',
54
image: '/images/airpods.jpg',
65
description:
@@ -13,7 +12,6 @@ const products = [
1312
numReviews: 12,
1413
},
1514
{
16-
_id: '2',
1715
name: 'iPhone 11 Pro 256GB Memory',
1816
image: '/images/phone.jpg',
1917
description:
@@ -26,7 +24,6 @@ const products = [
2624
numReviews: 8,
2725
},
2826
{
29-
_id: '3',
3027
name: 'Cannon EOS 80D DSLR Camera',
3128
image: '/images/camera.jpg',
3229
description:
@@ -39,7 +36,6 @@ const products = [
3936
numReviews: 12,
4037
},
4138
{
42-
_id: '4',
4339
name: 'Sony Playstation 4 Pro White Version',
4440
image: '/images/playstation.jpg',
4541
description:
@@ -52,7 +48,6 @@ const products = [
5248
numReviews: 12,
5349
},
5450
{
55-
_id: '5',
5651
name: 'Logitech G-Series Gaming Mouse',
5752
image: '/images/mouse.jpg',
5853
description:
@@ -65,7 +60,6 @@ const products = [
6560
numReviews: 10,
6661
},
6762
{
68-
_id: '6',
6963
name: 'Amazon Echo Dot 3rd Generation',
7064
image: '/images/alexa.jpg',
7165
description:

backend/data/users.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import bcrypt from 'bcryptjs'
2+
3+
const users = [
4+
{
5+
name: 'Admin User',
6+
7+
password: bcrypt.hashSync('123456', 10),
8+
isAdmin: true,
9+
},
10+
{
11+
name: 'John Doe',
12+
13+
password: bcrypt.hashSync('123456', 10),
14+
},
15+
{
16+
name: 'Janny RubyJane',
17+
18+
password: bcrypt.hashSync('123456', 10),
19+
},
20+
]
21+
22+
export default users

backend/middleware/errorMiddleware.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const notFound = (req, res, next) => {
2+
const error = new Error(`Not Found - ${req.originalUrl}`)
3+
res.status(404)
4+
next(error)
5+
}
6+
7+
const errorHandler = (err, req, res, next) => {
8+
const statusCode = res.statusCode === 200 ? 500 : res.statusCode
9+
res.status(statusCode)
10+
res.json({
11+
message: err.message,
12+
stack: process.env.NODE_ENV === 'production' ? null : err.stack,
13+
})
14+
}
15+
16+
export { notFound, errorHandler }

backend/models/orderModel.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import mongoose from 'mongoose'
2+
3+
const orderSchema = mongoose.Schema(
4+
{
5+
user: {
6+
type: mongoose.Schema.Types.ObjectId,
7+
required: true,
8+
ref: 'User',
9+
},
10+
orderItems: [
11+
{
12+
name: { type: String, required: true },
13+
qty: { type: Number, required: true },
14+
image: { type: String, required: true },
15+
price: { type: Number, required: true },
16+
product: {
17+
type: mongoose.Schema.Types.ObjectId,
18+
required: true,
19+
ref: 'Produc',
20+
},
21+
},
22+
],
23+
shippingAddress: {
24+
address: { type: String, required: true },
25+
city: { type: String, required: true },
26+
postalCode: { type: String, required: true },
27+
country: { type: String, required: true },
28+
},
29+
paymentMethod: {
30+
type: String,
31+
required: true,
32+
},
33+
paymentResult: {
34+
id: { type: String },
35+
status: { type: String },
36+
update_time: { type: String },
37+
email_address: { type: String },
38+
},
39+
taxPrice: {
40+
type: Number,
41+
required: true,
42+
},
43+
shippingPrice: {
44+
type: Number,
45+
required: true,
46+
default: 0.0,
47+
},
48+
totalPrice: {
49+
type: Number,
50+
required: true,
51+
default: 0.0,
52+
},
53+
isPaid: {
54+
type: Boolean,
55+
required: true,
56+
default: false,
57+
},
58+
paidAt: {
59+
type: Date,
60+
},
61+
isDelivered: {
62+
type: Number,
63+
required: true,
64+
default: 0.0,
65+
},
66+
deliveredAt: {
67+
type: Date,
68+
},
69+
},
70+
{
71+
timestamps: true,
72+
}
73+
)
74+
75+
const Order = mongoose.model('Order', orderSchema)
76+
export default Order

backend/models/productModel.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import mongoose from 'mongoose'
2+
3+
const reviewSchema = mongoose.Schema(
4+
{
5+
name: { type: String, required: true },
6+
rating: { type: Number, required: true },
7+
comment: { type: String, required: true },
8+
},
9+
{
10+
timestamps: true,
11+
}
12+
)
13+
14+
const productSchema = mongoose.Schema(
15+
{
16+
user: {
17+
type: mongoose.Schema.Types.ObjectId,
18+
required: true,
19+
ref: 'User',
20+
},
21+
name: {
22+
type: String,
23+
required: true,
24+
},
25+
image: {
26+
type: String,
27+
required: true,
28+
},
29+
brand: {
30+
type: String,
31+
required: true,
32+
},
33+
category: {
34+
type: String,
35+
required: true,
36+
},
37+
description: {
38+
type: String,
39+
required: true,
40+
},
41+
reviews: [reviewSchema],
42+
rating: {
43+
type: Number,
44+
required: true,
45+
default: 0,
46+
},
47+
numReviews: {
48+
type: Number,
49+
required: true,
50+
default: 0,
51+
},
52+
price: {
53+
type: Number,
54+
required: true,
55+
default: 0,
56+
},
57+
countInStock: {
58+
type: Number,
59+
required: true,
60+
default: 0,
61+
},
62+
},
63+
{
64+
timestamps: true,
65+
}
66+
)
67+
68+
const Product = mongoose.model('Product', productSchema)
69+
export default Product

backend/models/userModel.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import mongoose from 'mongoose'
2+
3+
const userSchema = mongoose.Schema({
4+
name: {
5+
type: String,
6+
required: true
7+
},
8+
email : {
9+
type: String,
10+
required: true,
11+
unique: true
12+
},
13+
password: {
14+
type: String,
15+
required: true
16+
},
17+
isAdmin: {
18+
type: Boolean,
19+
required: true,
20+
default: false
21+
}
22+
}, {
23+
timestamps: true
24+
})
25+
26+
const User = mongoose.model('User', userSchema)
27+
export default User

backend/routes/productRoutes.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import express from 'express'
2+
import asyncHandler from 'express-async-handler'
3+
const router = express.Router()
4+
import Product from '../models/productModel.js'
5+
6+
// @desc Fetch all products
7+
// @route GET /api/products
8+
// @access Public
9+
router.get(
10+
'/',
11+
asyncHandler(async (req, res) => {
12+
const products = await Product.find({})
13+
res.json(products)
14+
})
15+
)
16+
17+
// @desc Fetch single products
18+
// @route GET /api/products/:id
19+
// @access Public
20+
router.get(
21+
'/:id',
22+
asyncHandler(async (req, res) => {
23+
const product = await Product.findById(req.params.id)
24+
25+
if (product) {
26+
res.json(product)
27+
} else {
28+
res.status(404)
29+
throw new Error('Product not found')
30+
}
31+
})
32+
)
33+
34+
export default router

backend/seeder.js

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import mongoose from 'mongoose'
2+
import dotenv from 'dotenv'
3+
import colors from 'colors'
4+
import users from './data/users.js'
5+
import products from './data/products.js'
6+
import User from './models/userModel.js'
7+
import Product from './models/productModel.js'
8+
import Order from './models/orderModel.js'
9+
import connectDB from './config/db.js'
10+
11+
dotenv.config()
12+
13+
connectDB()
14+
15+
const importData = async () => {
16+
try {
17+
await Order.deleteMany()
18+
await Product.deleteMany()
19+
await User.deleteMany()
20+
21+
const createdUsers = await User.insertMany(users)
22+
23+
const adminUser = createdUsers[0]._id
24+
25+
const sampleProducts = products.map((product) => {
26+
return { ...product, user: adminUser }
27+
})
28+
29+
await Product.insertMany(sampleProducts)
30+
31+
console.log('Data Imported!! '.green.inverse)
32+
process.exit()
33+
} catch (error) {
34+
console.log(`${error}`.red.inverse)
35+
process.exit(1)
36+
}
37+
}
38+
39+
const destroyData = async () => {
40+
try {
41+
await Order.deleteMany()
42+
await Product.deleteMany()
43+
await User.deleteMany()
44+
45+
console.log('Data Destroyed!! '.red.inverse)
46+
process.exit()
47+
} catch (error) {
48+
console.log(`${error}`.red.inverse)
49+
process.exit(1)
50+
}
51+
}
52+
53+
if (process.argv[2] === '-d') {
54+
destroyData()
55+
} else {
56+
importData()
57+
}

0 commit comments

Comments
 (0)