init from origin + update
This commit is contained in:
34
server/routers/basket/auth.js
Normal file
34
server/routers/basket/auth.js
Normal file
@@ -0,0 +1,34 @@
|
||||
const router = require('express').Router()
|
||||
const checkPwd = require('pbkdf2-password')()
|
||||
const jwt = require('jsonwebtoken')
|
||||
const { BASKET_JWT_TOKEN } = require('./key')
|
||||
|
||||
const { getResponse, signUp, getUser, _idToId, requiredFields } = require('./controller')
|
||||
|
||||
router.post('/sign-in', requiredFields(['email', 'password']), async (req, res) => {
|
||||
try {
|
||||
const user = await getUser(req.body)
|
||||
// eslint-disable-next-line max-len
|
||||
checkPwd({ password: req.body.password, salt: user.salt }, async (err, pass, salt, hash) => {
|
||||
if (err) throw new Error(err)
|
||||
|
||||
if (user.pwd === hash) {
|
||||
const { pwd, salt: _salt, ...rest } = user
|
||||
const token = jwt.sign(_idToId(rest), BASKET_JWT_TOKEN)
|
||||
res.send(getResponse(null, { token, user: _idToId(rest) }))
|
||||
} else {
|
||||
res.status(400).send(getResponse('Неправильный email или пароль'))
|
||||
}
|
||||
})
|
||||
} catch (e) {
|
||||
res.status(400).send(getResponse(e.message))
|
||||
}
|
||||
})
|
||||
|
||||
router.post('/sign-up', requiredFields(['email', 'login', 'password']), async (req, res) => {
|
||||
let error = null
|
||||
const data = await signUp(req.body).catch((e) => error = e.message)
|
||||
res.status(error ? 400 : 200).send(getResponse(error, data))
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
25
server/routers/basket/categories.js
Normal file
25
server/routers/basket/categories.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const router = require('express').Router()
|
||||
const { expressjwt } = require('express-jwt')
|
||||
const ObjectId = require('mongodb').ObjectID
|
||||
|
||||
const { BASKET_JWT_TOKEN } = require('./key')
|
||||
|
||||
const { getResponse, getCategory, postCategory } = require('./controller')
|
||||
|
||||
router.use(expressjwt({ secret: BASKET_JWT_TOKEN, algorithms: ['HS256'] }))
|
||||
|
||||
router.get('/', async (req, res) => {
|
||||
const userId = new ObjectId(req.auth.id)
|
||||
let error = null
|
||||
const categoryData = await getCategory({ userId }).catch((e) => error = e.message)
|
||||
res.send(getResponse(error, categoryData))
|
||||
})
|
||||
|
||||
router.post('/', async (req, res) => {
|
||||
const userId = new ObjectId(req.auth.id)
|
||||
let error = null
|
||||
const categoryData = await postCategory({ userId, ...req.body }).catch((e) => error = e.message)
|
||||
res.send(getResponse(error, categoryData))
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
510
server/routers/basket/controller.js
Normal file
510
server/routers/basket/controller.js
Normal file
@@ -0,0 +1,510 @@
|
||||
const ObjectId = require('mongodb').ObjectID
|
||||
const getHash = require('pbkdf2-password')()
|
||||
|
||||
const { getDB } = require('../../utils/mongo')
|
||||
|
||||
const USERS_COLLECTION = 'users'
|
||||
const LISTS_COLLECTION = 'lists'
|
||||
const CATEGORY_COLLECTION = 'default_categories'
|
||||
const USER_CATEGROY_COLLECTION = 'user_categories'
|
||||
const ITEM_COLLECTION = 'items'
|
||||
const fakeUserId = 'fakeUserId'
|
||||
|
||||
let db = null
|
||||
|
||||
const connect = async () => {
|
||||
db = await getDB('basket')
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
await connect()
|
||||
const categoriesCollection = db.collection(CATEGORY_COLLECTION)
|
||||
const findData = await categoriesCollection.find({
|
||||
}).toArray()
|
||||
if (findData.length === 0) {
|
||||
await categoriesCollection.insertMany([
|
||||
{
|
||||
name: 'Продукты',
|
||||
color: '#08AE0F',
|
||||
},
|
||||
{
|
||||
name: 'Одежда',
|
||||
color: '#9D79B9',
|
||||
},
|
||||
{
|
||||
name: 'Бытовая химия',
|
||||
color: '#B11F1F',
|
||||
},
|
||||
{
|
||||
name: 'Лекарства',
|
||||
color: '#3414F5',
|
||||
},
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
init()
|
||||
|
||||
const _idToId = (data) => {
|
||||
const { _id, ...rest } = data
|
||||
|
||||
return {
|
||||
id: _id,
|
||||
...rest,
|
||||
}
|
||||
}
|
||||
|
||||
const _idToIdArray = (data) => {
|
||||
const _idToIdMap = data.map((item) => _idToId(item))
|
||||
|
||||
return _idToIdMap
|
||||
}
|
||||
|
||||
const getResponse = (error, data, success = true) => {
|
||||
if (error) {
|
||||
return {
|
||||
success: false,
|
||||
error,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
success,
|
||||
data,
|
||||
}
|
||||
}
|
||||
|
||||
const signUp = async ({ email, login, password }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const usersCollection = db.collection(USERS_COLLECTION)
|
||||
const userData = await usersCollection.findOne({
|
||||
$or: [{
|
||||
login,
|
||||
}, {
|
||||
email,
|
||||
}],
|
||||
})
|
||||
|
||||
if (userData?.login === login) {
|
||||
throw new Error('Логин занят')
|
||||
}
|
||||
if (userData?.email === email) {
|
||||
throw new Error('Email занят')
|
||||
}
|
||||
|
||||
getHash({ password }, async (err, pass, salt, hash) => {
|
||||
if (err) throw new Error(err)
|
||||
// eslint-disable-next-line max-len
|
||||
const { insertedCount } = await usersCollection.insertOne({ email, login, pwd: hash, salt })
|
||||
if (!insertedCount) throw new Error('insert error')
|
||||
})
|
||||
|
||||
return {}
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getUser = async ({ email }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const usersCollection = db.collection(USERS_COLLECTION)
|
||||
const userData = await usersCollection.findOne(
|
||||
{
|
||||
email,
|
||||
},
|
||||
)
|
||||
if (userData) return userData
|
||||
throw new Error('Неправильный email или пароль')
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const addList = async ({ userId = fakeUserId, ...data }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const insertData = await listsCollection.insertOne({
|
||||
userId,
|
||||
timeStamp: Date.now(),
|
||||
...data,
|
||||
})
|
||||
|
||||
const { insertedCount, ops } = insertData
|
||||
if (insertedCount) { return _idToId(ops[0]) }
|
||||
throw new Error('insert error')
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getLists = async ({ userId = fakeUserId }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const itemsCollection = db.collection(ITEM_COLLECTION)
|
||||
let newLists = []
|
||||
|
||||
const data = await listsCollection.find({
|
||||
userId,
|
||||
}).toArray()
|
||||
|
||||
await Promise.all(data.map(async (element) => {
|
||||
const total = await itemsCollection.countDocuments({
|
||||
parentId: element._id,
|
||||
})
|
||||
const purchased = await itemsCollection.countDocuments({
|
||||
parentId: element._id,
|
||||
bought: true,
|
||||
})
|
||||
|
||||
newLists.push({
|
||||
...element, total, purchased,
|
||||
})
|
||||
}))
|
||||
|
||||
newLists.sort((a, b) => (b.timeStamp - a.timeStamp))
|
||||
|
||||
return _idToIdArray(newLists)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
/* добавил логику рекурсивного удаления дочерних документов */
|
||||
const deleteDoc = async ({ id, tag = false }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const itemsCollection = db.collection(ITEM_COLLECTION)
|
||||
|
||||
const findData = await itemsCollection.find({
|
||||
parentId: new ObjectId(id),
|
||||
}).toArray()
|
||||
|
||||
findData.forEach(async (element) => {
|
||||
await deleteDoc({
|
||||
id: element._id,
|
||||
tag: true,
|
||||
})
|
||||
})
|
||||
|
||||
let delData = null
|
||||
if (tag) {
|
||||
delData = await itemsCollection.deleteOne({
|
||||
_id: new ObjectId(id),
|
||||
})
|
||||
} else {
|
||||
delData = await listsCollection.deleteOne({
|
||||
_id: new ObjectId(id),
|
||||
})
|
||||
}
|
||||
|
||||
const { deletedCount } = delData
|
||||
if (deletedCount) {
|
||||
return {
|
||||
}
|
||||
} throw new Error('no data to delete')
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const renameList = async ({ id, listName }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const data = await listsCollection.updateOne({
|
||||
_id: new ObjectId(id),
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
listName,
|
||||
},
|
||||
})
|
||||
|
||||
const { matchedCount } = data
|
||||
if (matchedCount) {
|
||||
const findData = await listsCollection.findOne({
|
||||
_id: new ObjectId(id),
|
||||
})
|
||||
return _idToId(findData)
|
||||
} throw new Error('no data to rename')
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const duplicateList = async ({ id, parentId = null }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(LISTS_COLLECTION)
|
||||
const itemsCollection = db.collection(ITEM_COLLECTION)
|
||||
|
||||
let addListData = null
|
||||
let newId = null
|
||||
|
||||
if (parentId) {
|
||||
const findData = await itemsCollection.findOne(
|
||||
{
|
||||
_id: new ObjectId(id),
|
||||
},
|
||||
)
|
||||
|
||||
const { _id, ...item } = findData
|
||||
item.parentId = parentId
|
||||
const insertData = await itemsCollection.insertOne({
|
||||
...item,
|
||||
})
|
||||
const { insertedCount } = insertData
|
||||
if (!insertedCount) throw new Error('insert new item error')
|
||||
} else {
|
||||
const findData = await listsCollection.findOne(
|
||||
{
|
||||
_id: new ObjectId(id),
|
||||
},
|
||||
)
|
||||
|
||||
const { _id, timeStamp, ...item } = findData
|
||||
item.listName = `(КОПИЯ) ${item.listName}`
|
||||
addListData = await addList({
|
||||
...item,
|
||||
})
|
||||
newId = addListData.id
|
||||
}
|
||||
|
||||
const childData = await itemsCollection.find({
|
||||
parentId: new ObjectId(id),
|
||||
}).toArray()
|
||||
|
||||
childData.forEach(async (element) => {
|
||||
await duplicateList({
|
||||
id: element._id, parentId: newId,
|
||||
})
|
||||
})
|
||||
|
||||
if (addListData) return _idToId(addListData)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getCategory = async ({ userId }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const categoriesCollection = db.collection(CATEGORY_COLLECTION)
|
||||
const defaultCategories = await categoriesCollection.find({
|
||||
}).toArray()
|
||||
const defaultCategoriesData = _idToIdArray(defaultCategories).map((dc) => ({
|
||||
...dc, userId,
|
||||
}))
|
||||
|
||||
const userCollection = db.collection(USER_CATEGROY_COLLECTION)
|
||||
const userCategoriesFilter = {}
|
||||
|
||||
if (userId) {
|
||||
userCategoriesFilter.userId = userId
|
||||
}
|
||||
const userFindData = await userCollection.find(userCategoriesFilter).toArray()
|
||||
|
||||
return [...defaultCategoriesData, ..._idToIdArray(userFindData)]
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const postCategory = async ({ userId = fakeUserId, ...categoryData }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const userCollection = db.collection(USER_CATEGROY_COLLECTION)
|
||||
const insertData = await userCollection.insertOne({
|
||||
userId, ...categoryData,
|
||||
})
|
||||
|
||||
// const {insertedCount, ops} = insertData
|
||||
// if (insertedCount)
|
||||
// _idToId(ops[0])
|
||||
// else
|
||||
// throw new Error('insert error')
|
||||
const userFindData = await userCollection.find({
|
||||
userId,
|
||||
}).toArray()
|
||||
return _idToIdArray(userFindData)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const getShoppingList = async ({ userId = fakeUserId, id }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const listsCollection = db.collection(ITEM_COLLECTION)
|
||||
const itemsList = await listsCollection.find({
|
||||
parentId: new ObjectId(id),
|
||||
}).toArray()
|
||||
const categoryList = await getCategory({ })
|
||||
const coloredItemsList = itemsList.map((item) => ({
|
||||
...item,
|
||||
// eslint-disable-next-line max-len
|
||||
color: categoryList.find((category) => String(category.id) === String(item.categoryId))?.color,
|
||||
}))
|
||||
|
||||
return _idToIdArray(coloredItemsList)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const addListItem = async ({ userId = fakeUserId, listId, categoryId, text }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const dataToInsert = {
|
||||
parentId: new ObjectId(listId),
|
||||
categoryId: new ObjectId(categoryId),
|
||||
text,
|
||||
count: 1,
|
||||
bought: false,
|
||||
createdBy: userId,
|
||||
createdDt: Date.now(),
|
||||
modifiedBy: userId,
|
||||
modifiedDt: Date.now(),
|
||||
}
|
||||
const itemCollection = db.collection(ITEM_COLLECTION)
|
||||
await itemCollection.insertOne(dataToInsert)
|
||||
|
||||
return _idToId(dataToInsert)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const boughtItem = async ({ userId = fakeUserId, itemId, bought }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
try {
|
||||
const itemCollection = db.collection(ITEM_COLLECTION)
|
||||
const chengedData = await itemCollection.findOneAndUpdate({
|
||||
_id: new ObjectId(itemId),
|
||||
},
|
||||
[{
|
||||
$set: {
|
||||
bought: { $eq: [false, '$bought'] },
|
||||
modifiedBy: userId,
|
||||
modifiedDt: Date.now(),
|
||||
},
|
||||
}])
|
||||
return _idToId(chengedData)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const incCountItem = async ({ userId = fakeUserId, itemId, count }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const itemCollection = db.collection(ITEM_COLLECTION)
|
||||
const chengedData = await itemCollection.findOneAndUpdate({
|
||||
_id: new ObjectId(itemId),
|
||||
},
|
||||
{
|
||||
$inc: {
|
||||
count,
|
||||
},
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
modifiedBy: userId,
|
||||
modifiedDt: Date.now(),
|
||||
},
|
||||
})
|
||||
const chengeData = await itemCollection.findOneAndUpdate({
|
||||
_id: new ObjectId(itemId),
|
||||
count: {
|
||||
$lt: 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
$set: {
|
||||
count: 1,
|
||||
modifiedBy: userId,
|
||||
modifiedDt: Date.now(),
|
||||
},
|
||||
})
|
||||
return _idToId(chengedData || chengeData)
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const deleteItem = async ({ itemId }) => {
|
||||
if (db === null) throw new Error('no db connection')
|
||||
|
||||
try {
|
||||
const itemCollection = db.collection(ITEM_COLLECTION)
|
||||
const findItemData = await itemCollection.find({
|
||||
_id: new ObjectId(itemId),
|
||||
})
|
||||
|
||||
findItemData.forEach((item) => {
|
||||
deleteItem({
|
||||
id: item._id,
|
||||
})
|
||||
})
|
||||
|
||||
const deleteItemData = await itemCollection.deleteOne({
|
||||
_id: new ObjectId(itemId),
|
||||
})
|
||||
|
||||
const { deletedButton } = deleteItemData
|
||||
if (deletedButton) {
|
||||
return {
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error(e)
|
||||
}
|
||||
}
|
||||
|
||||
const requiredFields = (fields) => (req, res, next) => {
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const fieldName of fields) {
|
||||
if (!req.body[fieldName]) {
|
||||
throw new Error(`Параметр ${fieldName} не установлен`)
|
||||
}
|
||||
}
|
||||
|
||||
next()
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getResponse,
|
||||
addList,
|
||||
getLists,
|
||||
deleteDoc,
|
||||
renameList,
|
||||
duplicateList,
|
||||
getCategory,
|
||||
postCategory,
|
||||
getShoppingList,
|
||||
addListItem,
|
||||
boughtItem,
|
||||
deleteItem,
|
||||
incCountItem,
|
||||
signUp,
|
||||
getUser,
|
||||
_idToId,
|
||||
requiredFields,
|
||||
}
|
||||
54
server/routers/basket/dashboard.js
Normal file
54
server/routers/basket/dashboard.js
Normal file
@@ -0,0 +1,54 @@
|
||||
const router = require('express').Router()
|
||||
const { expressjwt } = require('express-jwt')
|
||||
const ObjectId = require('mongodb').ObjectID
|
||||
|
||||
const { BASKET_JWT_TOKEN } = require('./key')
|
||||
|
||||
const {
|
||||
getResponse, addList,
|
||||
getLists, deleteDoc, renameList, duplicateList,
|
||||
} = require('./controller')
|
||||
|
||||
const wait = (req, res, next) => setTimeout(next, 0)
|
||||
|
||||
router.use(expressjwt({ secret: BASKET_JWT_TOKEN, algorithms: ['HS256'] }))
|
||||
|
||||
/* получить списки покупок*/
|
||||
router.get('/list', wait, async (req, res) => {
|
||||
const userId = new ObjectId(req.auth.id)
|
||||
let error = null
|
||||
const listData = await getLists({ userId }).catch((e) => error = e.message)
|
||||
res.status(error ? 400 : 200).send(getResponse(error, listData))
|
||||
})
|
||||
|
||||
/* удалить список*/
|
||||
router.delete('/list', wait, async (req, res) => {
|
||||
let error = null
|
||||
const listData = await deleteDoc(req.body).catch((e) => error = e.message)
|
||||
res.status(error ? 400 : 200).send(getResponse(error, listData))
|
||||
})
|
||||
|
||||
/* добавить новый список*/
|
||||
router.post('/list', wait, async (req, res) => {
|
||||
const userId = new ObjectId(req.auth.id)
|
||||
let error = null
|
||||
// eslint-disable-next-line max-len
|
||||
const listData = await addList({ userId, ...req.body }).catch((e) => error = e.message)
|
||||
res.status(error ? 400 : 200).send(getResponse(error, listData))
|
||||
})
|
||||
|
||||
/* переименовать список*/
|
||||
router.put('/list', wait, async (req, res) => {
|
||||
let error = null
|
||||
const listData = await renameList(req.body).catch((e) => error = e.message)
|
||||
res.status(error ? 400 : 200).send(getResponse(error, listData))
|
||||
})
|
||||
|
||||
/* дублировать список*/
|
||||
router.post('/list/duplicate', wait, async (req, res) => {
|
||||
let error = null
|
||||
const listData = await duplicateList(req.body).catch((e) => error = e.message)
|
||||
res.status(error ? 400 : 200).send(getResponse(error, listData))
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
9
server/routers/basket/index.js
Normal file
9
server/routers/basket/index.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const router = require('express').Router()
|
||||
|
||||
router.use('/dashboard', require('./dashboard'))
|
||||
router.use('/landing', require('./landing'))
|
||||
router.use('/categories', require('./categories'))
|
||||
router.use('/shoppingList', require('./listItem'))
|
||||
router.use('/auth', require('./auth'))
|
||||
|
||||
module.exports = router
|
||||
10
server/routers/basket/json/auth/sign-in.json
Normal file
10
server/routers/basket/json/auth/sign-in.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"data": {
|
||||
"token": "qwert",
|
||||
"user": {
|
||||
"id": "1234",
|
||||
"login": "eldar",
|
||||
"email": "www@www.ru"
|
||||
}
|
||||
}
|
||||
}
|
||||
23
server/routers/basket/json/categories/add/success.json
Normal file
23
server/routers/basket/json/categories/add/success.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"success": true,
|
||||
"data":
|
||||
{
|
||||
"category":[
|
||||
{
|
||||
"id":1,
|
||||
"name": "Продукты",
|
||||
"color": "#08AE0F"
|
||||
},
|
||||
{
|
||||
"id":2,
|
||||
"name": "Бытовая химия",
|
||||
"color": "#3414F5"
|
||||
},
|
||||
{
|
||||
"id":3,
|
||||
"name": "Одежда",
|
||||
"color": "#FA8803"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
18
server/routers/basket/json/categories/current/success.json
Normal file
18
server/routers/basket/json/categories/current/success.json
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"success": true,
|
||||
"data":
|
||||
{
|
||||
"category":[
|
||||
{
|
||||
"id":1,
|
||||
"name": "Продукты",
|
||||
"color": "#08AE0F"
|
||||
},
|
||||
{
|
||||
"id":2,
|
||||
"name": "Бытовая химия",
|
||||
"color": "#3414F5"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
3
server/routers/basket/json/dashboard/common/error.json
Normal file
3
server/routers/basket/json/dashboard/common/error.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"error": "Не получилось..."
|
||||
}
|
||||
8
server/routers/basket/json/dashboard/common/success.json
Normal file
8
server/routers/basket/json/dashboard/common/success.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"data": {
|
||||
"id": "vrgbtrgbtrbryn",
|
||||
"listName": "2 список",
|
||||
"purchased": 1,
|
||||
"total": 5
|
||||
}
|
||||
}
|
||||
4
server/routers/basket/json/dashboard/list/empty.json
Normal file
4
server/routers/basket/json/dashboard/list/empty.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": []
|
||||
}
|
||||
4
server/routers/basket/json/dashboard/list/error.json
Normal file
4
server/routers/basket/json/dashboard/list/error.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"success": false,
|
||||
"error": "Список не загрузился"
|
||||
}
|
||||
23
server/routers/basket/json/dashboard/list/success.json
Normal file
23
server/routers/basket/json/dashboard/list/success.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"id": "uuid1",
|
||||
"listName": "Состоялась 94-я церемония вручения премии «Оскар»: награда за лучший фильм присуждена картине...",
|
||||
"purchased": 0,
|
||||
"total": 5
|
||||
},
|
||||
{
|
||||
"id": "uuid2",
|
||||
"listName": "Второй список",
|
||||
"purchased": 1,
|
||||
"total": 5
|
||||
},
|
||||
{
|
||||
"id": "uuid3",
|
||||
"listName": "Первый список",
|
||||
"purchased": 5,
|
||||
"total": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
4
server/routers/basket/json/landing/error.json
Normal file
4
server/routers/basket/json/landing/error.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"success": false,
|
||||
"error": "Ошибка получения данных для Landing"
|
||||
}
|
||||
80
server/routers/basket/json/landing/success.json
Normal file
80
server/routers/basket/json/landing/success.json
Normal file
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"features": [
|
||||
{
|
||||
"id": "1",
|
||||
"nameImg": "image-shopping-list.png",
|
||||
"altImg": "image-shopping-list",
|
||||
"title": "Список покупок",
|
||||
"text": "Отличный интерфейс, удобно и понятно для использования. Удобно! Если нет нужного в списке, можно добавить и оно сохраниться."
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"nameImg": "image-shared-access.png",
|
||||
"altImg": "image-shared-access",
|
||||
"title": "Общий доступ",
|
||||
"text": "Делитесь списками покупок, чтобы планировать вместе с другими. Синхронизация для нескольких покупателей — это вещь!"
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"nameImg": "image-messaging.png",
|
||||
"altImg": "image-messaging",
|
||||
"title": "Обмен сообщениями",
|
||||
"text": "Хотите что-то обсудить при составление списка покупок, то есть возможность обмениваться сообщениями в режиме реального времени."
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"nameImg": "image-share-photos.png",
|
||||
"altImg": "mage-share-photos",
|
||||
"title": "Делитесь фотографиями",
|
||||
"text": "Не перепутайте товар при покупки — загружайте фотографии и обменивайтесь ими с другими пользователями. Это очень удобно!"
|
||||
},
|
||||
{
|
||||
"id": "5",
|
||||
"nameImg": "image-prices.png",
|
||||
"altImg": "image-prices",
|
||||
"title": "Цены",
|
||||
"text": "Расходы под контролем — вводите цены в спиок покупок. Приложение оценит стоимость и будет известно, чего ожидать на кассе."
|
||||
},
|
||||
{
|
||||
"id": "6",
|
||||
"nameImg": "image-ecology.png",
|
||||
"altImg": "image-ecology",
|
||||
"title": "Экология",
|
||||
"text": "Бумажные списки покупок — это деревья, которые могли бы еще расти. Вместо тысяч слов — возьми с собой приложение!"
|
||||
},
|
||||
{
|
||||
"id": "7",
|
||||
"nameImg": "image-buy.png",
|
||||
"altImg": "image-buy",
|
||||
"title": "Покупайте",
|
||||
"text": "97% пользователей поробывали приложение и теперь совершают меньше лишних и ненужных покупок. Покупайте нужное!"
|
||||
}
|
||||
],
|
||||
"helps": [
|
||||
{
|
||||
"id": "1",
|
||||
"title": "Как работает вМагазин?",
|
||||
"text": "Задача организации, в особенности же консультация с широким активом обеспечивает широкому кругу специалистов новых принципов формирования материально-технической и кадровой базы."
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"title": "Условия оплаты",
|
||||
"text": "Задача организации, в особенности же консультация с широким активом обеспечивает широкому кругу специалистов новых принципов формирования материально-технической и кадровой базы."
|
||||
},
|
||||
{
|
||||
"id": "3",
|
||||
"title": "Как с нами связаться",
|
||||
"text": "Задача организации, в особенности же консультация с широким активом обеспечивает широкому кругу специалистов новых принципов формирования материально-технической и кадровой базы."
|
||||
},
|
||||
{
|
||||
"id": "4",
|
||||
"title": "Текст",
|
||||
"text": "Задача организации, в особенности же консультация с широким активом обеспечивает широкому кругу специалистов новых принципов формирования материально-технической и кадровой базы."
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
3
server/routers/basket/json/listItem/item/error.json
Normal file
3
server/routers/basket/json/listItem/item/error.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"error": "Не удалось изменить..."
|
||||
}
|
||||
15
server/routers/basket/json/listItem/item/success.json
Normal file
15
server/routers/basket/json/listItem/item/success.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"success": true,
|
||||
"data":
|
||||
{
|
||||
"id": 23,
|
||||
"categoryId": 1,
|
||||
"text": "Курица",
|
||||
"count": 17,
|
||||
"bought": false,
|
||||
"createdBy": "",
|
||||
"createdDt": "",
|
||||
"modifiedBy": "",
|
||||
"modifiedDt": ""
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"success": false,
|
||||
"error": "Ошибка получения данных"
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"success": true,
|
||||
"data":
|
||||
{
|
||||
"id": 8,
|
||||
"listName":"Мой список",
|
||||
"data":[
|
||||
{
|
||||
"id": 1,
|
||||
"categoryId": 1,
|
||||
"text": "Курица",
|
||||
"count": 2,
|
||||
"bought": true,
|
||||
"delete":false
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"categoryId":1,
|
||||
"text": "Хлеб",
|
||||
"count": 1,
|
||||
"bought":false,
|
||||
"delete":true
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"categoryId": "3",
|
||||
"text": "Шампунь",
|
||||
"count": 1,
|
||||
"bought":true,
|
||||
"delete":false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
5
server/routers/basket/key.js
Normal file
5
server/routers/basket/key.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const BASKET_JWT_TOKEN = 'super super secret key'
|
||||
|
||||
module.exports = {
|
||||
BASKET_JWT_TOKEN,
|
||||
}
|
||||
7
server/routers/basket/landing.js
Normal file
7
server/routers/basket/landing.js
Normal file
@@ -0,0 +1,7 @@
|
||||
const router = require('express').Router()
|
||||
|
||||
router.get('/', (req, res) => {
|
||||
res.send(require('./json/landing/success.json'))
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
67
server/routers/basket/listItem.js
Normal file
67
server/routers/basket/listItem.js
Normal file
@@ -0,0 +1,67 @@
|
||||
const router = require('express').Router()
|
||||
const { expressjwt } = require('express-jwt')
|
||||
const ObjectId = require('mongodb').ObjectID
|
||||
|
||||
const { BASKET_JWT_TOKEN } = require('./key')
|
||||
|
||||
const { getShoppingList, deleteItem, boughtItem, incCountItem, getResponse, addListItem } = require('./controller')
|
||||
|
||||
router.use(expressjwt({ secret: BASKET_JWT_TOKEN, algorithms: ['HS256'] }))
|
||||
|
||||
router.get('/:id', async (req, res) => {
|
||||
const userId = new ObjectId(req.auth.id)
|
||||
let error = null
|
||||
// eslint-disable-next-line no-return-assign
|
||||
const { id } = req.params
|
||||
// eslint-disable-next-line no-return-assign
|
||||
const listData = await getShoppingList({ userId, id }).catch((e) => error = e.message)
|
||||
res.send(getResponse(error, listData))
|
||||
})
|
||||
|
||||
router.post('/item/:id', async (req, res) => {
|
||||
const userId = new ObjectId(req.auth.id)
|
||||
let error = null
|
||||
// eslint-disable-next-line no-return-assign
|
||||
const { id } = req.params
|
||||
const { categoryId, text } = req.body
|
||||
const shoppingListData = await addListItem({
|
||||
userId, listId: id, categoryId, text,
|
||||
// eslint-disable-next-line no-return-assign
|
||||
}).catch((e) => error = e.message)
|
||||
res.send(getResponse(error, shoppingListData))
|
||||
})
|
||||
|
||||
router.patch('/item/:id', async (req, res) => {
|
||||
const userId = new ObjectId(req.auth.id)
|
||||
let error = null
|
||||
// eslint-disable-next-line no-return-assign
|
||||
const { id } = req.params
|
||||
const { bought } = req.body.item
|
||||
// eslint-disable-next-line no-return-assign
|
||||
// eslint-disable-next-line max-len
|
||||
const itemData = await boughtItem({ userId, itemId: id, bought }).catch((e) => error = e.message)
|
||||
res.send(getResponse(error, itemData))
|
||||
})
|
||||
|
||||
router.put('/item/:id', async (req, res) => {
|
||||
const userId = new ObjectId(req.auth.id)
|
||||
let error = null
|
||||
// eslint-disable-next-line no-return-assign
|
||||
const { id } = req.params
|
||||
const { count } = req.body
|
||||
// eslint-disable-next-line no-return-assign
|
||||
// eslint-disable-next-line max-len
|
||||
const itemData = await incCountItem({ userId, itemId: id, count }).catch((e) => error = e.message)
|
||||
res.send(getResponse(error, itemData))
|
||||
})
|
||||
|
||||
router.delete('/item/:id', async (req, res) => {
|
||||
let error = null
|
||||
// eslint-disable-next-line no-return-assign
|
||||
const { id } = req.params
|
||||
// eslint-disable-next-line no-return-assign
|
||||
const itemData = await deleteItem({ itemId: id }).catch((e) => error = e.message)
|
||||
res.send(getResponse(error, itemData))
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
Reference in New Issue
Block a user