-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ec1fef2
commit 57b6316
Showing
57 changed files
with
4,756 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
.gitattributes merge=copy-merge | ||
.gitignore merge=copy-merge | ||
package.json merge=copy-merge | ||
package-lock.json merge=copy-merge | ||
pnpm-lock.yaml merge=copy-merge | ||
setup.sh merge=copy-merge | ||
|
||
# __CRIO__ | ||
__CRIO__/metadata.json merge=copy-merge | ||
|
||
# backend/ | ||
backend/db/products.db merge=copy-merge | ||
backend/routes/auth.js merge=copy-merge | ||
backend/routes/cart.js merge=copy-merge | ||
backend/routes/product.js merge=copy-merge | ||
backend/routes/user.js merge=copy-merge | ||
backend/package.json merge=copy-merge | ||
backend/package-lock.json merge=copy-merge | ||
backend/pnpm-lock.yaml merge=copy-merge | ||
|
||
# public/ | ||
public/avatar.png merge=copy-merge | ||
public/index.html merge=copy-merge | ||
public/icon.svg merge=copy-merge | ||
public/robots.txt merge=copy-merge | ||
public/favicon.ico merge=copy-merge | ||
public/manifest.json merge=copy-merge | ||
|
||
# src/ | ||
src/setupTests.js merge=copy-merge | ||
|
||
|
||
# src/__tests__ | ||
src/__tests__/Login.test.js merge=copy-merge | ||
src/__tests__/App.test.js merge=copy-merge | ||
src/__tests__/Register.test.js merge=copy-merge | ||
src/__tests__/Cart.test.js merge=copy-merge | ||
src/__tests__/Checkout.test.js merge=copy-merge | ||
src/__tests__/Products.test.js merge=copy-merge | ||
src/__tests__/ProductCard.test.js merge=copy-merge |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
.env.local | ||
.env.development.local | ||
.env.test.local | ||
.env.production.local | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
testReport.json | ||
.vercel | ||
|
||
package-lock.json | ||
pnpm-lock.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"liveServer.settings.port": 8083 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"module_id": "ME_QKART_FRONTEND_V2_MODULE_CHECKOUT", | ||
"me_id": "ME_QKART_FRONTEND_V2" | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
node_modules | ||
node_modules/ | ||
db/users.db | ||
yarn.lock |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"port": 8082, | ||
"jwtSecret": "DeveloperSecretForEvaluationDoNotHardCodeLikeThisInRealLifeProductionApplications" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
const nedb = require('nedb'); | ||
const users = new nedb({ filename: 'db/users.db', autoload: true }) | ||
const products = new nedb({ filename: 'db/products.db', autoload: true }); | ||
|
||
module.exports.users = users | ||
module.exports.products = products |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{"name":"UNIFACTOR Mens Running Shoes","category":"Fashion","cost":50,"rating":5,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/42d4d057-8704-4174-8d74-e5e9052677c6.png","_id":"BW0jAAeDJmlZCF8i"} | ||
{"name":"YONEX Smash Badminton Racquet","category":"Sports","cost":100,"rating":5,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/64b930f7-3c82-4a29-a433-dbc6f1493578.png","_id":"KCRwjF7lN97HnEaY"} | ||
{"name":"Tan Leatherette Weekender Duffle","category":"Fashion","cost":150,"rating":4,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/ff071a1c-1099-48f9-9b03-f858ccc53832.png","_id":"PmInA797xJhMIPti"} | ||
{"name":"The Minimalist Slim Leather Watch","category":"Electronics","cost":60,"rating":5,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/5b478a4a-bf81-467c-964c-1881887799b7.png","_id":"TwMM4OAhmK0VQ93S"} | ||
{"name":"Atomberg 1200mm BLDC motor","category":"Home & Kitchen","cost":80,"rating":5,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/e8e0832c-8f16-4468-95a0-8aaed387a169.png","_id":"a4sLtEcMpzabRyfx"} | ||
{"name":"Bonsai Spirit Tree Table Lamp","category":"Home & Kitchen","cost":80,"rating":5,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/b49ee2dc-6458-42de-851d-b014ac24cd8e.png","_id":"upLK9JbQ4rMhTwt4"} | ||
{"name":"Stylecon 9 Seater RHS Sofa Set ","category":"Home & Kitchen","cost":650,"rating":3,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/7ad56699-20c9-4778-a783-4021e5f0864c.png","_id":"v4sLtEcMpzabRyf"} | ||
{"name":"Diamond Pendant (0.01 ct, IJ-SI)","category":"Fashion","cost":1000,"rating":5,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/95d6d42d-3a37-4efb-ad10-3bcbbb599856.png","_id":"v4sLtEcMpzabRyfx"} | ||
{"name":"Apple iPad Pro with Apple M1 chip","category":"Electronics","cost":900,"rating":5,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/82ac2e7b-e4dd-4a5b-8dbc-3260225d7eb2.png","_id":"w4sLtEcMpzabRyfx"} | ||
{"name":"OnePlus (55 inches) Q1 Series 4K","category":"Electronics","cost":1200,"rating":5,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/a9ca1e8b-8783-4be3-83f8-d06409016e15.png","_id":"x4sLtEcMpzabRyfx"} | ||
{"name":"Thinking, Fast and Slow","category":"Books","cost":15,"rating":5,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/cdb64440-5e95-4aaa-858b-8c12ee316d93.png","_id":"y4sLtEcMpzabRyfx"} | ||
{"name":"GREY DOUBLE BUTTON BLAZER","category":"Fashion","cost":75,"rating":4,"image":"https://crio-directus-assets.s3.ap-south-1.amazonaws.com/869ec5e2-52d2-4b8e-bc6b-57eace9ab39e.png","_id":"z4sLtEcMpzabRyfx"} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
const express = require('express'); | ||
const cors = require('cors'); | ||
const config = require('./config.json'); | ||
const app = express(); | ||
|
||
app.use(cors()); | ||
app.use(express.json()); | ||
|
||
const authRouter = require('./routes/auth') | ||
const productRouter = require('./routes/product') | ||
const cartRouter = require('./routes/cart') | ||
const userRouter = require('./routes/user') | ||
|
||
app.use('/api/v1/auth', authRouter); | ||
app.use('/api/v1/products', productRouter); | ||
app.use('/api/v1/cart', cartRouter); | ||
app.use('/api/v1/user', userRouter); | ||
|
||
const port = process.env.PORT || config.port | ||
app.listen(port, () => { | ||
console.log(`QKart Backend running at port ${port}`); | ||
}); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"name": "react-me-backend", | ||
"version": "0.1.0", | ||
"private": true, | ||
"scripts": { | ||
"start": "node index.js" | ||
}, | ||
"dependencies": { | ||
"cors": "^2.8.5", | ||
"express": "^4.17.1", | ||
"jsonwebtoken": "^8.5.1", | ||
"nanoid": "^3.1.12", | ||
"nedb": "^1.8.0", | ||
"@testing-library/dom": "^8.13.0", | ||
"typescript": "^3.2.1", | ||
"@babel/core": "^7.17.10" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
var express = require("express"); | ||
var router = express.Router(); | ||
const { handleError } = require("../utils"); | ||
var { users } = require("../db"); | ||
const crypto = require("crypto"); | ||
const jwt = require("jsonwebtoken"); | ||
const config = require("../config.json"); | ||
|
||
router.post("/register", (req, res) => { | ||
console.log(`GET request to "/auth/register" received for user}`); | ||
|
||
users.findOne({ username: req.body.username }, (err, user) => { | ||
if (err) { | ||
return handleError(res, err); | ||
} | ||
if (user) { | ||
return res.status(400).json({ | ||
success: false, | ||
message: "Username already exists", | ||
}); | ||
} | ||
// if (req.body.username.length < 6 || req.body.username.length > 32) { | ||
// return res.status(400).json({ | ||
// success: false, | ||
// message: | ||
// 'Username must be between 6 and 32 characters in length' | ||
// }); | ||
// } | ||
// if (req.body.password.length < 6 || req.body.password.length > 32) { | ||
// return res.status(400).json({ | ||
// success: false, | ||
// message: | ||
// 'Password must be between 6 and 32 characters in length' | ||
// }); | ||
// } | ||
users.insert({ | ||
username: req.body.username, | ||
password: sha256(req.body.password), | ||
balance: 5000, | ||
cart: [], | ||
addresses: [], | ||
}); | ||
|
||
console.log(`Registered user: ${req.body.username}`); | ||
|
||
return res.status(201).json({ | ||
success: true, | ||
}); | ||
}); | ||
}); | ||
|
||
router.post("/login", (req, res) => { | ||
console.log(`POST request to "/auth/login" received`); | ||
|
||
users.findOne({ username: req.body.username }, (err, user) => { | ||
if (err) { | ||
return handleError(res, err); | ||
} | ||
if (!user) { | ||
return res.status(400).json({ | ||
success: false, | ||
message: "Username does not exist", | ||
}); | ||
} | ||
if (user.password !== sha256(req.body.password)) { | ||
return res.status(400).json({ | ||
success: false, | ||
message: "Password is incorrect", | ||
}); | ||
} | ||
const token = jwt.sign({ username: user.username }, config.jwtSecret, { | ||
expiresIn: "6h", | ||
}); | ||
|
||
console.log(`Logged in as user: ${req.body.username}`); | ||
|
||
return res.status(201).json({ | ||
success: true, | ||
token: token, | ||
username: user.username, | ||
balance: user.balance, | ||
}); | ||
}); | ||
}); | ||
|
||
const sha256 = (input) => | ||
crypto.createHash("sha256").update(input, "utf8").digest("hex"); | ||
|
||
module.exports = router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
var express = require("express"); | ||
var router = express.Router(); | ||
const { handleError, verifyAuth, getProduct } = require("../utils"); | ||
var { users, products } = require("../db"); | ||
|
||
// Cart Controller | ||
router.get("/", verifyAuth, (req, res) => { | ||
console.log(`GET request to "/cart" received`); | ||
|
||
return res.status(200).json(req.user.cart); | ||
}); | ||
|
||
router.post("/", verifyAuth, async (req, res) => { | ||
console.log(`POST request to "/cart" received`); | ||
|
||
products.findOne({ _id: req.body.productId }, async (err, product) => { | ||
if (err) { | ||
return handleError(res, err); | ||
} | ||
if (!product) { | ||
return res | ||
.status(404) | ||
.json({ success: false, message: "Product doesn't exist" }); | ||
} | ||
|
||
const index = await req.user.cart.findIndex( | ||
(element) => element.productId === req.body.productId | ||
); | ||
|
||
if (index === -1) { | ||
req.user.cart.push({ | ||
productId: req.body.productId, | ||
qty: req.body.qty, | ||
}); | ||
} else if (req.body.qty === 0) { | ||
// delete | ||
req.user.cart.splice(index, 1); | ||
} else { | ||
//modify | ||
req.user.cart[index].qty = req.body.qty; | ||
} | ||
users.update( | ||
{ _id: req.user._id }, | ||
{ $set: { cart: req.user.cart } }, | ||
{}, | ||
(err) => { | ||
if (err) { | ||
handleError(res, err); | ||
} | ||
|
||
console.log( | ||
`User ${req.user.username}'s cart updated to`, | ||
req.user.cart | ||
); | ||
|
||
return res.status(200).json(req.user.cart); | ||
} | ||
); | ||
}); | ||
}); | ||
|
||
router.post("/checkout", verifyAuth, async (req, res) => { | ||
console.log( | ||
`POST request received to "/cart/checkout": ${req.user.username}` | ||
); | ||
|
||
let total = 0; | ||
for (let element of req.user.cart) { | ||
try { | ||
const product = await getProduct(element.productId); | ||
if (product == null) { | ||
throw new Error("Invalid product in cart. "); | ||
} | ||
total = total + element.qty * product.cost; | ||
} catch (error) { | ||
handleError(res, error); | ||
} | ||
} | ||
if (total === 0) { | ||
return res.status(400).json({ success: false, message: "Cart is empty" }); | ||
} | ||
if (req.user.balance < total) { | ||
return res.status(400).json({ | ||
success: false, | ||
message: "Wallet balance not sufficient to place order", | ||
}); | ||
} | ||
if (!req.body.addressId) { | ||
return res.status(400).json({ | ||
success: false, | ||
message: "Address not set", | ||
}); | ||
} | ||
const addressIndex = await req.user.addresses.findIndex( | ||
(element) => element._id === req.body.addressId | ||
); | ||
if (addressIndex === -1) { | ||
return res | ||
.status(404) | ||
.json({ success: false, message: "Bad address specified" }); | ||
} | ||
req.user.balance -= total; | ||
console.log("Mock order placed"); | ||
console.log("Cart", req.user.cart); | ||
console.log("Total cost", total); | ||
console.log("Address", req.user.addresses[addressIndex]); | ||
// Now clear cart | ||
req.user.cart = []; | ||
users.update({ _id: req.user._id }, req.user, {}, (err) => { | ||
if (err) { | ||
handleError(res, err); | ||
} | ||
return res.status(200).json({ | ||
success: true, | ||
}); | ||
}); | ||
}); | ||
|
||
module.exports = router; |
Oops, something went wrong.