back-end done

This commit is contained in:
Amir Mohamadi
2020-12-10 16:36:48 +03:30
parent 80a7abafb7
commit bc5e617778
92 changed files with 5217 additions and 3379 deletions
+2 -25
View File
@@ -1,10 +1,10 @@
const jwt = require('jsonwebtoken');
const Admin = require('./models/admin/Admin')
const User = require('./models/user/User')
const config = {
// secret for generating jwt token
secretKey: '2664debdbef6fdd2ae52ba2c9cd4d1d15f3cdca31a641aacad1a5c43cda91b55a145b3f4c573f69aeba3c942bf55417593ff74f7d192a5664358ee753ea09e8e'
secretKey: 'b8a537eefc8e8e938509bd6a557e51d8f9459842691b013254fb8f31e6d6c78713f65fad589f0b036481907b7014e249d28da1ea359f8a5b7f59da3aa5b0455f'
}
module.exports = config
@@ -31,26 +31,3 @@ module.exports.isAdmin = function (req, res, next) {
return res.status(401).json({message: 'unauthorized'})
}
}
// check if user logged in
module.exports.isUser = function (req, res, next) {
const token = req.headers.authorization
if (token) {
// check if token is not destroyed
User.findOne({token: token}, (err, user) => {
if (err) throw err
if (user) {
// verifies secret and checks if the token is expired
jwt.verify(user.token.replace(/^Bearer\s/, ''), config.secretKey, (err, decoded) => {
if (err) {
return res.status(401).json({message: 'unauthorized'})
} else {
return next()
}
})
} else return res.status(401).json({message: 'unauthorized'})
})
} else {
return res.status(401).json({message: 'unauthorized'})
}
}
@@ -1,385 +0,0 @@
const AboutPageContent = require('../models/AboutPageContent')
const dateformat = require('dateformat')
const {body, validationResult} = require('express-validator')
const jimp = require('jimp')
const fs = require('fs')
module.exports.create = [
[
// fa
body('fa_page_title')
.notEmpty().withMessage('تیتر بالای صفحه نباید خالی باشد.'),
body('fa_s1_title')
.notEmpty().withMessage('تیتر بخش اول نباید خالی باشد.'),
body('fa_s1_caption')
.notEmpty().withMessage('توضیحات بخش اول نباید خالی باشد.'),
body('fa_s2_title')
.notEmpty().withMessage('تیتر بخش دوم نباید خالی باشد.'),
body('fa_s2_caption')
.notEmpty().withMessage('توضیحات بخش دوم نباید خالی باشد.'),
body('fa_s2_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش دوم نباید خالی باشد.'),
body('fa_s3_title')
.notEmpty().withMessage('تیتر بخش سوم نباید خالی باشد.'),
body('fa_s3_caption')
.notEmpty().withMessage('توضیحات بخش سوم نباید خالی باشد.'),
body('fa_s3_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش سوم نباید خالی باشد.'),
body('fa_s4_text')
.notEmpty().withMessage('متن بخش چهارم نباید خالی باشد.'),
body('fa_last_section_title')
.notEmpty().withMessage('تیتر بخش آخر نباید خالی باشد.'),
body('fa_last_section_text')
.notEmpty().withMessage('متن بخش آخر نباید خالی باشد.'),
// en
body('en_page_title')
.notEmpty().withMessage('تیتر بالای صفحه نباید خالی باشد.'),
body('en_s1_title')
.notEmpty().withMessage('تیتر بخش اول نباید خالی باشد.'),
body('en_s1_caption')
.notEmpty().withMessage('توضیحات بخش اول نباید خالی باشد.'),
body('en_s2_title')
.notEmpty().withMessage('تیتر بخش دوم نباید خالی باشد.'),
body('en_s2_caption')
.notEmpty().withMessage('توضیحات بخش دوم نباید خالی باشد.'),
body('en_s2_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش دوم نباید خالی باشد.'),
body('en_s3_title')
.notEmpty().withMessage('تیتر بخش سوم نباید خالی باشد.'),
body('en_s3_caption')
.notEmpty().withMessage('توضیحات بخش سوم نباید خالی باشد.'),
body('en_s3_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش سوم نباید خالی باشد.'),
body('en_s4_text')
.notEmpty().withMessage('متن بخش چهارم نباید خالی باشد.'),
body('en_last_section_title')
.notEmpty().withMessage('تیتر بخش آخر نباید خالی باشد.'),
body('en_last_section_text')
.notEmpty().withMessage('متن بخش آخر نباید خالی باشد.'),
// de
body('de_page_title')
.notEmpty().withMessage('تیتر بالای صفحه نباید خالی باشد.'),
body('de_s1_title')
.notEmpty().withMessage('تیتر بخش اول نباید خالی باشد.'),
body('de_s1_caption')
.notEmpty().withMessage('توضیحات بخش اول نباید خالی باشد.'),
body('de_s2_title')
.notEmpty().withMessage('تیتر بخش دوم نباید خالی باشد.'),
body('de_s2_caption')
.notEmpty().withMessage('توضیحات بخش دوم نباید خالی باشد.'),
body('de_s2_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش دوم نباید خالی باشد.'),
body('de_s3_title')
.notEmpty().withMessage('تیتر بخش سوم نباید خالی باشد.'),
body('de_s3_caption')
.notEmpty().withMessage('توضیحات بخش سوم نباید خالی باشد.'),
body('de_s3_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش سوم نباید خالی باشد.'),
body('de_s4_text')
.notEmpty().withMessage('متن بخش چهارم نباید خالی باشد.'),
body('de_last_section_title')
.notEmpty().withMessage('تیتر بخش آخر نباید خالی باشد.'),
body('de_last_section_text')
.notEmpty().withMessage('متن بخش آخر نباید خالی باشد.'),
// tr
body('tr_page_title')
.notEmpty().withMessage('تیتر بالای صفحه نباید خالی باشد.'),
body('tr_s1_title')
.notEmpty().withMessage('تیتر بخش اول نباید خالی باشد.'),
body('tr_s1_caption')
.notEmpty().withMessage('توضیحات بخش اول نباید خالی باشد.'),
body('tr_s2_title')
.notEmpty().withMessage('تیتر بخش دوم نباید خالی باشد.'),
body('tr_s2_caption')
.notEmpty().withMessage('توضیحات بخش دوم نباید خالی باشد.'),
body('tr_s2_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش دوم نباید خالی باشد.'),
body('tr_s3_title')
.notEmpty().withMessage('تیتر بخش سوم نباید خالی باشد.'),
body('tr_s3_caption')
.notEmpty().withMessage('توضیحات بخش سوم نباید خالی باشد.'),
body('tr_s3_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش سوم نباید خالی باشد.'),
body('tr_s4_text')
.notEmpty().withMessage('متن بخش چهارم نباید خالی باشد.'),
body('tr_last_section_title')
.notEmpty().withMessage('تیتر بخش آخر نباید خالی باشد.'),
body('tr_last_section_text')
.notEmpty().withMessage('متن بخش آخر نباید خالی باشد.'),
// it
body('it_page_title')
.notEmpty().withMessage('تیتر بالای صفحه نباید خالی باشد.'),
body('it_s1_title')
.notEmpty().withMessage('تیتر بخش اول نباید خالی باشد.'),
body('it_s1_caption')
.notEmpty().withMessage('توضیحات بخش اول نباید خالی باشد.'),
body('it_s2_title')
.notEmpty().withMessage('تیتر بخش دوم نباید خالی باشد.'),
body('it_s2_caption')
.notEmpty().withMessage('توضیحات بخش دوم نباید خالی باشد.'),
body('it_s2_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش دوم نباید خالی باشد.'),
body('it_s3_title')
.notEmpty().withMessage('تیتر بخش سوم نباید خالی باشد.'),
body('it_s3_caption')
.notEmpty().withMessage('توضیحات بخش سوم نباید خالی باشد.'),
body('it_s3_imageCaption')
.notEmpty().withMessage('توضیحات عکس بخش سوم نباید خالی باشد.'),
body('it_s4_text')
.notEmpty().withMessage('متن بخش چهارم نباید خالی باشد.'),
body('it_last_section_title')
.notEmpty().withMessage('تیتر بخش آخر نباید خالی باشد.'),
body('it_last_section_text')
.notEmpty().withMessage('متن بخش آخر نباید خالی باشد.'),
],
(req, res) => {
// check validations
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
////////////////// catch form data
const data = {
aboutPage_details: {
fa: {
page_title: req.body.fa_page_title,
s1_title: req.body.fa_s1_title,
s1_caption: req.body.fa_s1_caption,
s2_title: req.body.fa_s2_title,
s2_caption: req.body.fa_s2_caption,
s2_imageCaption: req.body.fa_s2_imageCaption,
s3_title: req.body.fa_s3_title,
s3_caption: req.body.fa_s3_caption,
s3_imageCaption: req.body.fa_s3_imageCaption,
s4_text: req.body.fa_s4_text,
last_section_title: req.body.fa_last_section_title,
last_section_text: req.body.fa_last_section_text
},
en: {
page_title: req.body.en_page_title,
s1_title: req.body.en_s1_title,
s1_caption: req.body.en_s1_caption,
s2_title: req.body.en_s2_title,
s2_caption: req.body.en_s2_caption,
s2_imageCaption: req.body.en_s2_imageCaption,
s3_title: req.body.en_s3_title,
s3_caption: req.body.en_s3_caption,
s3_imageCaption: req.body.en_s3_imageCaption,
s4_text: req.body.en_s4_text,
last_section_title: req.body.en_last_section_title,
last_section_text: req.body.en_last_section_text
},
de: {
page_title: req.body.de_page_title,
s1_title: req.body.de_s1_title,
s1_caption: req.body.de_s1_caption,
s2_title: req.body.de_s2_title,
s2_caption: req.body.de_s2_caption,
s2_imageCaption: req.body.de_s2_imageCaption,
s3_title: req.body.de_s3_title,
s3_caption: req.body.de_s3_caption,
s3_imageCaption: req.body.de_s3_imageCaption,
s4_text: req.body.de_s4_text,
last_section_title: req.body.de_last_section_title,
last_section_text: req.body.de_last_section_text
},
tr: {
page_title: req.body.tr_page_title,
s1_title: req.body.tr_s1_title,
s1_caption: req.body.tr_s1_caption,
s2_title: req.body.tr_s2_title,
s2_caption: req.body.tr_s2_caption,
s2_imageCaption: req.body.tr_s2_imageCaption,
s3_title: req.body.tr_s3_title,
s3_caption: req.body.tr_s3_caption,
s3_imageCaption: req.body.tr_s3_imageCaption,
s4_text: req.body.tr_s4_text,
last_section_title: req.body.tr_last_section_title,
last_section_text: req.body.tr_last_section_text
},
it: {
page_title: req.body.it_page_title,
s1_title: req.body.it_s1_title,
s1_caption: req.body.it_s1_caption,
s2_title: req.body.it_s2_title,
s2_caption: req.body.it_s2_caption,
s2_imageCaption: req.body.it_s2_imageCaption,
s3_title: req.body.it_s3_title,
s3_caption: req.body.it_s3_caption,
s3_imageCaption: req.body.it_s3_imageCaption,
s4_text: req.body.it_s4_text,
last_section_title: req.body.it_last_section_title,
last_section_text: req.body.it_last_section_text
}
}
}
function createImages(image, imageName) {
if (image) {
jimp.read(image.data)
.then(img => {
img
.cover(380, 510)
.write(`./static/uploads/images/about/${imageName}`, (err, file) => {
if (err) console.log(err)
})
})
}
}
let heroFile
let heroFileName
let s2File
let s2FileName
let s3File
let s3FileName
let lastSectionFile
let lastSectionFileName
if (req.files) {
if (req.files.page_hero) {
heroFile = req.files.page_hero
heroFileName = 'image_' + Date.now() + 1 + '.' + heroFile.mimetype.split('/')[1]
}
if (req.files.s2_image) {
s2File = req.files.s2_image
s2FileName = 'image_' + Date.now() + 2 + '.' + s2File.mimetype.split('/')[1]
}
if (req.files.s3_image) {
s3File = req.files.s3_image
s3FileName = 'image_' + Date.now() + 3 + '.' + s3File.mimetype.split('/')[1]
}
if (req.files.last_section_image) {
lastSectionFile = req.files.last_section_image
lastSectionFileName = 'image_' + Date.now() + 4 + '.' + lastSectionFile.mimetype.split('/')[1]
}
}
/////////////// save to database
if (req.body._id) {
if (req.files) {
if (heroFile) {
if (heroFile.size / 1024 > 500) return res.status(422).json({validation: {page_hero: {msg: 'حجم عکس نباید بیشتر از 500 کیلوبایت باشد.'}}})
data.page_hero = heroFileName
heroFile.mv(`./static/uploads/images/about/${heroFileName}`, err => {
if (err) console.log(err)
})
}
if (s2File) {
data.s2_image = s2FileName
createImages(s2File, s2FileName)
}
if (s3File) {
data.s3_image = s3FileName
createImages(s3File, s3FileName)
}
if (lastSectionFile) {
if (lastSectionFile.size / 1024 > 500) return res.status(422).json({validation: {last_section_image: {msg: 'حجم عکس نباید بیشتر از 500 کیلوبایت باشد.'}}})
data.last_section_image = lastSectionFileName
lastSectionFile.mv(`./static/uploads/images/about/${lastSectionFileName}`, err => {
if (err) console.log(err)
})
}
}
data.updated_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
AboutPageContent.findByIdAndUpdate(req.body._id, data, (err, oldData) => {
if (err) console.log(err)
if (req.files) {
if (heroFile) {
fs.unlink(`./static/${oldData.page_hero}`, err => {
if (err) console.log(err)
})
}
if (s2File) {
fs.unlink(`./static/${oldData.s2_image}`, err => {
if (err) console.log(err)
})
}
if (s3File) {
fs.unlink(`./static/${oldData.s3_image}`, err => {
if (err) console.log(err)
})
}
if (lastSectionFile) {
fs.unlink(`./static/${oldData.last_section_image}`, err => {
if (err) console.log(err)
})
}
}
AboutPageContent.findByIdAndUpdate(req.body._id)
.then(data => {
return res.json(data)
})
})
} else {
if (req.files) {
if (heroFile) {
if (heroFile.size / 1024 > 500) return res.status(422).json({validation: {page_hero: {msg: 'حجم عکس نباید بیشتر از 500 کیلوبایت باشد.'}}})
data.page_hero = heroFileName
heroFile.mv(`./static/uploads/images/about/${heroFileName}`, err => {
if (err) console.log(err)
})
} else {
return res.status(422).json({validation: {page_hero: {msg: 'عکس بخش اول اجباری است.'}}})
}
if (s2File) {
data.s2_image = s2FileName
createImages(s2File, s2FileName)
} else {
return res.status(422).json({validation: {s2_image: {msg: 'عکس بخش دوم اجباری است.'}}})
}
if (s3File) {
data.s3_image = s3FileName
createImages(s3File, s3FileName)
} else {
return res.status(422).json({validation: {s3_image: {msg: 'عکس بخش سوم اجباری است.'}}})
}
if (lastSectionFile) {
if (lastSectionFile.size / 1024 > 500) return res.status(422).json({validation: {last_section_image: {msg: 'حجم عکس نباید بیشتر از 500 کیلوبایت باشد.'}}})
data.last_section_image = lastSectionFileName
lastSectionFile.mv(`./static/uploads/images/about/${lastSectionFileName}`, err => {
if (err) console.log(err)
})
} else {
return res.status(422).json({validation: {last_section_image: {msg: 'عکس بخش آخر اجباری است.'}}})
}
} else {
return res.status(422).json({
validation: {
page_hero: {msg: 'عکس بخش اول اجباری است.'},
s2_image: {msg: 'عکس بخش دوم اجباری است.'},
s3_image: {msg: 'عکس بخش سوم اجباری است.'},
last_section_image: {msg: 'عکس بخش آخر اجباری است.'}
}
})
}
data.created_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
const aboutContent = new AboutPageContent(data)
aboutContent.save((err, data) => {
if (err) return res.status(500).json(err)
return res.json(data)
})
}
}
]
module.exports.get = [
(req, res) => {
AboutPageContent.findOne({}, (err, data) => {
if (err) return res.status(404).json({message: err})
return res.json(data)
})
}
]
+24 -18
View File
@@ -4,28 +4,30 @@ const dateformat = require('dateformat')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')
const config = require('../config')
const v_m = require('../validation_messages')
/////////////////////////////////////////////////////////////////////// register
module.exports.register = [
[
body('name')
.isLength({min: 4}).withMessage('حداقل 4 کاراکتر'),
.isLength({min: 2}).withMessage(v_m['fa'].min_char.min2),
body('username')
.isLength({min: 4}).withMessage('حداقل 4 کاراکتر')
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
.custom((value, {req}) => {
return Admin.findOne({username: value})
.then(admin => {
if (admin && admin.username === value) return Promise.reject('این نام کاربری از قبل وجود دارد.')
if (admin && admin.username === value) return Promise.reject(v_m['fa'].duplicated.username)
else return true
})
}),
body('password')
.isLength({min: 4}).withMessage('حداقل 4 کاراکتر')
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
.custom((value, {req}) => {
return value === req.body.password_confirmation
}).withMessage('پسورد ها یکی نیست.')
if (value === req.body.password_confirmation) return true
else return Promise.reject(v_m['fa'].response.passwords_not_match)
})
],
(req, res) => {
const errors = validationResult(req)
@@ -34,7 +36,6 @@ module.exports.register = [
const data = {}
data.name = req.body.name
data.username = req.body.username
data.scope = 'admin'
data.created_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
bcrypt.genSalt(10, (err, salt) => {
@@ -45,7 +46,7 @@ module.exports.register = [
const admin = new Admin(data)
admin.save(err => {
if (err) console.log(err)
return res.json({message: 'Admin added.'})
return res.json({message: v_m['fa'].response.success_save})
})
})
})
@@ -57,20 +58,26 @@ module.exports.register = [
module.exports.login = [
[
body('username')
.isLength({min: 4}).withMessage('حداقل 4 کاراکتر')
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
.bail()
.if((value, {req}) => {
return req.body.password && req.body.password.length >= 4
})
.custom((value, {req}) => {
return Admin.findOne({username: value})
.then(admin => {
if (!admin) return Promise.reject('ادمینی با این نام وجود ندارد.')
if (!admin) return Promise.reject(v_m['fa'].not_found.admin_id)
else return true
})
}),
body('password')
.isLength({min: 4}).withMessage('حداقل 4 کاراکتر'),
.notEmpty().withMessage(v_m['fa'].required.password)
.bail()
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4),
body('remember_me')
.exists().withMessage('پارامتر remember_me الزامی است.')
.exists().withMessage(v_m['fa'].required.remember_me)
.bail()
.isBoolean().withMessage('مقدار باید از جنس Boolean باشد.')
],
@@ -82,18 +89,17 @@ module.exports.login = [
if (err) console.log(err)
bcrypt.compare(req.body.password, user.password, (err, isMatch) => {
if (err) console.log(err)
if (!isMatch) return res.status(422).json({validation: {password: {msg: 'پسورد اشتباه است.'}}})
if (!isMatch) return res.status(422).json({validation: {password: {msg: v_m['fa'].not_found.password}}})
let token
if (req.body.remember_me) token = jwt.sign({_id: user._id}, config.secretKey)
else token = jwt.sign({_id: user._id}, config.secretKey, {expiresIn: '1h'})
user.token = token
user.markModified('token')
user.save(err => {
if (err) console.log(err)
return res.json({token: token})
})
return res.json({token: token})
})
})
}
@@ -106,11 +112,11 @@ module.exports.logout = [
if (token) {
Admin.findOneAndUpdate({token: token}, {token: null}, (err, oldData) => {
if (err) console.log(err)
if (oldData) return res.json({message: 'You are logged out.'})
return res.status(401).json({message: 'Your not logged in'})
if (oldData) return res.json({message: v_m['fa'].response.logged_out})
return res.status(401).json({message: v_m['fa'].response.not_logged_in})
})
} else {
return res.status(401).json({message: 'Your not logged in'})
return res.status(401).json({message: v_m['fa'].response.not_logged_in})
}
}
]
+14 -87
View File
@@ -2,56 +2,28 @@ const BlogCategory = require('../models/blog/BlogCategory')
const BlogPost = require('../models/blog/BlogPost')
const dateformat = require('dateformat')
const {body, validationResult} = require('express-validator')
const v_m = require('../validation_messages')
module.exports.create = [
[
body('fa_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.fa.name': value}).then(category => {
if (category) return Promise.reject('این نام از قبل وجود دارد.')
if (category) return Promise.reject(v_m['fa'].duplicated.title)
return true
})
}),
body('en_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.en.name': value}).then(category => {
if (category) return Promise.reject('این نام از قبل وجود دارد.')
return true
})
}),
body('de_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.de.name': value}).then(category => {
if (category) return Promise.reject('این نام از قبل وجود دارد.')
return true
})
}),
body('tr_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.tr.name': value}).then(category => {
if (category) return Promise.reject('این نام از قبل وجود دارد.')
return true
})
}),
body('it_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.it.name': value}).then(category => {
if (category) return Promise.reject('این نام از قبل وجود دارد.')
if (category) return Promise.reject(v_m['fa'].duplicated.title)
return true
})
})
],
(req, res) => {
const errors = validationResult(req)
@@ -64,22 +36,13 @@ module.exports.create = [
},
en: {
name: req.body.en_name
},
de: {
name: req.body.de_name
},
tr: {
name: req.body.tr_name
},
it: {
name: req.body.it_name
}
},
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
})
blogCategory.save(err => {
if (err) console.log(err)
return res.json({message: 'دسته بندی اضافه شد.'})
return res.json({message: v_m['fa'].response.success_save})
})
}
]
@@ -108,47 +71,20 @@ module.exports.getOne = [
module.exports.update = [
[
body('fa_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.fa.name': value}).then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('این نام از قبل وجود دارد.')
if (category && category._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title)
return true
})
}),
body('en_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.en.name': value}).then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('این نام از قبل وجود دارد.')
return true
})
}),
body('de_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.de.name': value}).then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('این نام از قبل وجود دارد.')
return true
})
}),
body('tr_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.tr.name': value}).then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('این نام از قبل وجود دارد.')
return true
})
}),
body('it_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return BlogCategory.findOne({'blogCategory_details.it.name': value}).then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('این نام از قبل وجود دارد.')
if (category && category._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title)
return true
})
})
@@ -164,22 +100,13 @@ module.exports.update = [
},
en: {
name: req.body.en_name
},
de: {
name: req.body.de_name
},
tr: {
name: req.body.tr_name
},
it: {
name: req.body.it_name
}
},
updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
BlogCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err)
return res.json({message: 'دسته بندی بروزرسانی شد.'})
return res.json({message: v_m['fa'].response.success_save})
})
}
]
@@ -187,12 +114,12 @@ module.exports.update = [
module.exports.delete = [
(req, res) => {
BlogPost.find({category: req.params.id}, (err, categories) => {
BlogPost.find({category: req.params.id}, (err, posts) => {
if (err) console.log(err)
if (!categories.length) {
if (!posts.length) {
BlogCategory.findByIdAndDelete(req.params.id, (err) => {
if (err) return res.status(404).json({message: err})
return res.json({message: 'دسته بندی حذف شد.'})
return res.json({message: v_m['fa'].response.success_save})
})
} else {
return res.status(500).json({message: 'نمیتوان دسته بندی هایی که دارای پست هستند را پاک کرد.'})
+49 -185
View File
@@ -3,102 +3,48 @@ const dateformat = require('dateformat')
const {body, validationResult} = require('express-validator')
const fs = require('fs')
const jimp = require('jimp')
const v_m = require('../validation_messages')
module.exports.create = [
[
// title
body('fa_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.isLength({max: 120}).withMessage(v_m['fa'].max_char.max120)
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.fa.title': value}).then(post => {
if (post) return Promise.reject('عنوان تکراری است.')
if (post) return Promise.reject(v_m['fa'].duplicated.title)
return true
})
}),
body('en_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.isLength({max: 120}).withMessage(v_m['fa'].max_char.max120)
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.en.title': value}).then(post => {
if (post) return Promise.reject('عنوان تکراری است.')
return true
})
}),
body('de_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.de.title': value}).then(post => {
if (post) return Promise.reject('عنوان تکراری است.')
return true
})
}),
body('tr_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.tr.title': value}).then(post => {
if (post) return Promise.reject('عنوان تکراری است.')
return true
})
}),
body('it_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.it.title': value}).then(post => {
if (post) return Promise.reject('عنوان تکراری است.')
if (post) return Promise.reject(v_m['fa'].duplicated.title)
return true
})
}),
// description
body('fa_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
.notEmpty().withMessage(v_m['fa'].required.description),
body('en_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('de_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('tr_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('it_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
.notEmpty().withMessage(v_m['fa'].required.description),
// short description
body('fa_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
.notEmpty().withMessage(v_m['fa'].required.description),
body('en_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
body('de_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
body('tr_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
body('it_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
.notEmpty().withMessage(v_m['fa'].required.description),
body('category')
.notEmpty().withMessage('دسته بندی را انتخاب کنید.')
.notEmpty().withMessage(v_m['fa'].required.category)
],
(req, res) => {
const errors = validationResult(req)
@@ -107,25 +53,24 @@ module.exports.create = [
let cover
let coverName
// 305 X 170
// 1370 x 556
// 460 X 320
// 1920 x 720
if (req.files && req.files.cover) {
cover = req.files.cover
coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1]
if (cover.size / 1024 > 500) return res.status(422).json({validation: {cover: {msg: 'حجم عکس نباید بیشتر از 500 کیلوبایت باشد.'}}})
} else {
return res.status(422).json({validation: {cover: {msg: 'کاور اجباری است.'}}})
return res.status(422).json({validation: {cover: {msg: v_m['fa'].required.cover}}})
}
jimp.read(cover.data)
.then(img => {
img
.cover(1370, 688)
.cover(1920, 720)
.quality(70)
.write(`./static/uploads/images/blog/${coverName}`)
.resize(305, jimp.AUTO)
.cover(305, 170)
.resize(460, jimp.AUTO)
.cover(460, 320)
.write(`./static/uploads/images/blog/thumb_${coverName}`)
})
@@ -140,21 +85,6 @@ module.exports.create = [
title: req.body.en_title,
description: req.body.en_description,
short_description: req.body.en_short_description
},
de: {
title: req.body.de_title,
description: req.body.de_description,
short_description: req.body.de_short_description
},
tr: {
title: req.body.tr_title,
description: req.body.tr_description,
short_description: req.body.tr_short_description
},
it: {
title: req.body.it_title,
description: req.body.it_description,
short_description: req.body.it_short_description
}
},
cover: coverName,
@@ -166,7 +96,7 @@ module.exports.create = [
const post = new BlogPost(data)
post.save(err => {
if (err) console.log(err)
return res.json({message: 'پست با موفقیت اضافه شد.'})
return res.json({message: v_m['fa'].response.success_save})
})
}
]
@@ -196,97 +126,44 @@ module.exports.update = [
[
// title
body('fa_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.isLength({max: 120}).withMessage(v_m['fa'].max_char.max120)
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.fa.title': value}).then(post => {
if (post && post._id.toString() !== req.params.id) return Promise.reject('عنوان تکراری است.')
if (post && post._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title)
return true
})
}),
body('en_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.isLength({max: 120}).withMessage(v_m['fa'].max_char.max120)
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.en.title': value}).then(post => {
if (post && post._id.toString() !== req.params.id) return Promise.reject('عنوان تکراری است.')
return true
})
}),
body('de_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.de.title': value}).then(post => {
if (post && post._id.toString() !== req.params.id) return Promise.reject('عنوان تکراری است.')
return true
})
}),
body('tr_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.tr.title': value}).then(post => {
if (post && post._id.toString() !== req.params.id) return Promise.reject('عنوان تکراری است.')
return true
})
}),
body('it_title')
.notEmpty().withMessage('عنوان نباید خالی باشد.')
.bail()
.isLength({max: 60}).withMessage('حداکثر 60 کاراکتر مجاز است.')
.bail()
.custom((value, {req}) => {
return BlogPost.findOne({'post_details.it.title': value}).then(post => {
if (post && post._id.toString() !== req.params.id) return Promise.reject('عنوان تکراری است.')
if (post && post._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title)
return true
})
}),
// description
body('fa_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
.notEmpty().withMessage(v_m['fa'].required.description),
body('en_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('de_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('tr_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('it_description')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
.notEmpty().withMessage(v_m['fa'].required.description),
// short description
body('fa_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
.notEmpty().withMessage(v_m['fa'].required.description),
body('en_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
body('de_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
body('tr_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
body('it_short_description')
.notEmpty().withMessage('توضیح کوتاه نباید خالی باشد.')
.bail()
.isLength({max: 120}).withMessage('حداکثر 120 کاراکتر مجاز است.'),
.notEmpty().withMessage(v_m['fa'].required.description),
body('category')
.notEmpty().withMessage('دسته بندی را انتخاب کنید.')
.notEmpty().withMessage(v_m['fa'].required.category)
],
(req, res) => {
const errors = validationResult(req)
@@ -304,21 +181,6 @@ module.exports.update = [
title: req.body.en_title,
description: req.body.en_description,
short_description: req.body.en_short_description
},
de: {
title: req.body.de_title,
description: req.body.de_description,
short_description: req.body.de_short_description
},
tr: {
title: req.body.tr_title,
description: req.body.tr_description,
short_description: req.body.tr_short_description
},
it: {
title: req.body.it_title,
description: req.body.it_description,
short_description: req.body.it_short_description
}
},
published: req.body.published,
@@ -326,8 +188,9 @@ module.exports.update = [
updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
// 305 X 170
// 1370 x 556
// 460 X 320
// 1920 x 720
let cover
let coverName
@@ -335,28 +198,29 @@ module.exports.update = [
cover = req.files.cover
coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1]
if (cover.size / 1024 > 500) return res.status(422).json({validation: {cover: {msg: 'حجم عکس نباید بیشتر از 500 کیلوبایت باشد.'}}})
data.cover = coverName
jimp.read(cover.data)
.then(img => {
img
.cover(1370, 688)
.cover(1920, 720)
.write(`./static/uploads/images/blog/${coverName}`)
.resize(305, jimp.AUTO)
.cover(305, 170)
.resize(460, jimp.AUTO)
.cover(460, 320)
.write(`./static/uploads/images/blog/thumb_${coverName}`)
})
}
BlogPost.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err)
if (cover && cover.data) fs.unlink(`./static/${oldData.cover}`, err => {
if (err) console.log(err)
})
if (cover && cover.data) fs.unlink(`./static/${oldData.thumb}`, err => {
if (err) console.log(err)
})
return res.json({message: 'پست با موفقیت بروزرسانی شد.'})
if (cover && cover.data) {
fs.unlink(`./static/${oldData.cover}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${oldData.thumb}`, err => {
if (err) console.log(err)
})
}
return res.json({message: v_m['fa'].response.success_save})
})
}
]
@@ -372,7 +236,7 @@ module.exports.delete = [
fs.unlink(`./static/${post.thumb}`, err => {
if (err) console.log(err)
})
return res.json({message: 'پست حذف شد.'})
return res.json({message: v_m['fa'].response.success_remove})
})
}
]
-81
View File
@@ -1,81 +0,0 @@
const Broadcast = require('../models/Broadcast')
const {body, validationResult} = require('express-validator')
const dateformat = require('dateformat')
module.exports.create = [
[
body('title')
.isLength({min: 2}).withMessage('حداقل 2 کاراکتر'),
body('message')
.isLength({min: 10}).withMessage('حداقل 10 کاراکتر'),
body('locale')
.notEmpty().withMessage('زبان پیام را انتخاب کنید')
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = {
title: req.body.title,
message: req.body.message,
admin_id: req.body.admin_id,
locale: req.body.locale,
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
const broadcast = new Broadcast(data)
broadcast.save((err, data) => {
if (err) console.log(err)
return res.json(data)
})
}
]
module.exports.getAll = [
(req, res) => {
Broadcast.find({})
.then(messages => {
return res.json(messages)
})
.catch(err => {
console.log(err)
})
}
]
module.exports.getOne = [
(req, res) => {
Broadcast.findById(req.params.id)
.then(message => {
if (!message.read.includes(req.body.user_id)) {
message.read.push(req.body.user_id)
message.save(err => {
if (err) console.log(err)
return res.json(message)
})
} else {
return res.json(message)
}
})
.catch(err => {
console.log(err)
})
}
]
module.exports.delete = [
(req, res) => {
Broadcast.findByIdAndDelete(req.params.id)
.then(message => {
return res.json({message: 'Message deleted.'})
})
.catch(err => {
return res.status(404).json(err)
})
}
]
+7 -1
View File
@@ -49,6 +49,12 @@ module.exports.create = [
return v_m[req.body.locale].format.email
}),
body('reason')
.custom((value, {req}) => {
if (!value) return Promise.reject(v_m[req.body.locale].required.reason)
else return true
}),
body('message')
.isLength({min: 50})
.withMessage((value, {req}) => {
@@ -66,7 +72,7 @@ module.exports.create = [
phone_number: req.body.phone_number,
email: req.body.email,
message: req.body.message,
user_id: req.body.user_id,
reason: req.body.reason,
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
const message = new ContactPageMessage(data)
@@ -0,0 +1,58 @@
const Reason = require('../models/ContactUsReason')
const {body, validationResult} = require('express-validator')
const dateformat = require('dateformat')
const v_m = require('../validation_messages')
module.exports.create = [
[
body('fa_reason')
.notEmpty().withMessage(v_m['fa'].required.title),
body('en_reason')
.notEmpty().withMessage(v_m['fa'].required.title)
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = {
reason_details: {
fa: {
reason: req.body.fa_reason
},
en: {
reason: req.body.en_reason
}
},
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
const reason = new Reason(data)
reason.save(err => {
if (err) console.log(err)
Reason.find({}, (err2, data) => {
if (err2) console.log(err2)
return res.json(data)
})
})
}
]
module.exports.getAll = [
(req, res) => {
Reason.find({}, (err, data) => {
if (err) console.log(err)
return res.json(data)
})
}
]
module.exports.delete = [
(req, res) => {
Reason.findByIdAndDelete(req.params.id, (err, reason) => {
if (err) console.log(err)
return res.json({message: v_m['fa'].response.success_remove})
})
}
]
-89
View File
@@ -1,89 +0,0 @@
const Gallery = require('../models/Gallery')
const jimp = require('jimp')
const fs = require('fs')
const dateFormat = require('dateformat')
///////////////////////////////////////////////////////////////////////////////////////////// create image
module.exports.create = [
(req, res) => {
let file
let fileName
////////////// validate image upload
if (req.files) {
file = req.files.image
fileName = 'gallery_' + Date.now() + '.' + file.mimetype.split('/')[1]
jimp.read(file.data)
.then(img => {
img
.cover(940, 620, jimp.HORIZONTAL_ALIGN_CENTER | jimp.VERTICAL_ALIGN_MIDDLE)
.write(`./static/uploads/images/gallery/${fileName}`, (err, img) => {
if (err) console.log(err)
})
.resize(335, jimp.AUTO)
.write(`./static/uploads/images/gallery/thumb/thumb_${fileName}`, (err, img) => {
if (err) console.log(err)
})
let gallery = new Gallery({
image: fileName,
created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
})
gallery.save((err, image) => {
if (err) return res.status(500).json(err)
Gallery.find({})
.then(images => {
return res.json(images)
})
.catch(err => {
return res.status(500).json(err)
})
})
})
.catch(err => {
console.log(err)
})
} else {
return res.status(422).json({validation: {image: {msg: 'عکس اجباری است'}}})
}
}
]
///////////////////////////////////////////////////////////////////////////////////////////// get all images
module.exports.getAll = [
(req, res) => {
Gallery.find({}, (err, images) => {
if (err) return res.json({errors: err})
return res.json(images)
})
}
]
///////////////////////////////////////////////////////////////////////////////////////////// get one image
module.exports.getOne = [
(req, res) => {
Gallery.findById(req.params.id, (err, image) => {
if (err) return res.json({errors: err})
return res.json(image)
})
}
]
///////////////////////////////////////////////////////////////////////////////////////////// delete image
module.exports.delete = [
(req, res) => {
Gallery.findByIdAndRemove(req.params.id, (err, data) => {
if (err) return res.json({error: err})
fs.unlink(`./static/${data.image}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${data.thumb}`, err => {
if (err) console.log(err)
})
return res.json({message: 'تصویر حذف شد'})
})
}
]
-36
View File
@@ -1,36 +0,0 @@
const locales = [
{
name: 'فارسی',
value: 'fa',
currency: 'ريال'
},
{
name: 'انگلیسی',
value: 'en',
currency: 'USD'
},
{
name: 'آلمانی',
value: 'de',
currency: 'EUR'
},
{
name: 'ترکی',
value: 'tr',
currency: 'TL'
},
{
name: 'ایتالیایی',
value: 'it',
currency: 'EUR'
}
]
module.exports.locales = locales
module.exports.get = [
(req, res) => {
return res.json(locales)
}
]
+50
View File
@@ -0,0 +1,50 @@
const MainCatalog = require('../models/MainCatalog')
const dateformat = require('dateformat')
const v_m = require('../validation_messages')
const fs = require('fs')
module.exports.create = [
(req, res) => {
if (!req.files || !req.files.pdf) return res.status(422).json({validation: {pdf: {msg: v_m['fa'].required.file}}})
if (req.files.pdf.mimetype.split('/')[1] !== 'pdf') return res.status(422).json({validation: {pdf: {msg: v_m['fa'].file_types.pdf}}})
MainCatalog.find({}, (err, catalogs) => {
if (catalogs.length) {
let firstFile = catalogs[0]
fs.unlink(`./static/${firstFile.file}`, err => {
if (err) console.log(err)
firstFile.file = req.files.pdf.name
firstFile.created_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
firstFile.save((err1, data) => {
if (err1) console.log(err1)
req.files.pdf.mv(`./static/uploads/pdf/${req.files.pdf.name}`)
return res.json(firstFile)
})
})
} else {
new MainCatalog({
file: req.files.pdf.name,
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}).save((err, data) => {
if (err) console.log(err)
req.files.pdf.mv(`./static/uploads/pdf/${req.files.pdf.name}`)
return res.json(data)
})
}
})
}
]
module.exports.get = [
(req, res) => {
MainCatalog.find({}, (err, catalog) => {
if (err) console.log(err)
if (catalog.length) return res.json(catalog[0])
else return res.json({})
})
}
]
-298
View File
@@ -1,298 +0,0 @@
const Cart_Item = require('../models/user/Cart_item')
const Order = require('../models/user/Order')
const User = require('../models/user/User')
const localeController = require('./localeController')
const Product = require('../models/product/Product')
const {body, validationResult} = require('express-validator')
const dateformat = require('dateformat')
const v_m = require('../validation_messages')
////////////////////////////////////// cart
module.exports.addToCart = [
[
body('user_id')
.custom((value, {req}) => {
return User.findById(value)
.then(user => {
if (user) return true
})
.catch(err => {
return Promise.reject(v_m[req.body.locale].not_found.user_id)
})
}),
body('product_id')
.custom((value, {req}) => {
return Product.findById(value)
.then(product => {
if (product) return true
})
.catch(err => {
return Promise.reject(v_m[req.body.locale].not_found.item_id)
})
}),
body('quantity')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.quantity
})
.bail()
.isNumeric()
.withMessage((value, {req}) => {
return v_m[req.body.locale].format.number
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json(errors)
Cart_Item.findOne({product_id: req.body.product_id, user_id: req.body.user_id})
.then(item => {
item.quantity = Number(item.quantity) + Number(req.body.quantity)
item.updated_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
item.markModified('quantity')
item.markModified('updated_at')
item.save()
return res.json({message: v_m[req.body.locale].response.success_save})
})
.catch(err => {
const data = {
user_id: req.body.user_id,
product_id: req.body.product_id,
quantity: req.body.quantity,
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
const cartItem = new Cart_Item(data)
cartItem.save((err, data) => {
if (err) console.log(err)
return res.json({message: v_m[req.body.locale].response.success_save})
})
})
}
]
module.exports.getCartItems = [
(req, res) => {
Cart_Item.find({user_id: req.params.user_id}, (err, data) => {
if (err) console.log(err)
return res.json(data)
})
}
]
module.exports.updateCart = [
(req, res) => {
Cart_Item.findById(req.params.item_id)
.then(item => {
item.quantity = Number(req.body.quantity)
item.updated_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
item.markModified('quantity')
item.markModified('updated_at')
item.save()
return res.json({message: v_m[req.body.locale].response.success_save})
})
.catch(err => {
return res.status(404).json({message: v_m[req.body.locale].not_found.item_id})
})
}
]
module.exports.deleteFromCart = [
(req, res) => {
Cart_Item.findByIdAndDelete(req.params.item_id)
.then(item => {
Cart_Item.find({user_id: item.user_id})
.then(items => {
return res.json(items)
})
})
.catch(err => {
return res.status(404).json({message: v_m['en'].not_found.item_id})
})
}
]
////////////////////////////////////// order
module.exports.addOrder = [
[
body('user_id')
.custom((value, {req}) => {
return User.findById(value)
.then(user => {
return true
})
.catch(err => {
return Promise.reject(v_m[req.body.locale].not_found.user_id)
})
})
],
//////////////////// validation step
(req, res, next) => {
Cart_Item.find({user_id: req.body.user_id})
.then(items => {
// check if cart is not empty
if (items.length) {
// check product stock
let outOfRun = []
items.forEach(async (item, index) => {
await Product.findById(item.product_id)
.then(product => {
if (product.stock < item.quantity) {
outOfRun.push({
product_id: product._id,
category_id: product.category,
stock: product.stock
})
item.remove()
}
if (index + 1 === items.length) {
if (!outOfRun.length) return next()
else return res.status(422).json(outOfRun)
}
})
})
} else {
return res.status(404).json({message: v_m[req.body.locale].response.cart_empty})
}
})
},
//////////////////// save order
(req, res) => {
Cart_Item.find({user_id: req.body.user_id})
.then(items => {
// save the order
const orderData = {
user_id: req.body.user_id,
number: Date.now(),
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
const order = new Order(orderData)
order.save((err, order) => {
if (err) console.log(err)
// get price unit for items
let unit = localeController.locales.filter(item => {
return item.value === req.body.locale
})[0].currency
// add incomplete status to order
order.statuses.push({
status: 'incomplete',
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
})
// add each item (Cart_Item result) to the order (saved Order result) and then remove it
items.forEach((item, index) => {
// get the price of each item depend on order locale
Product.findById(item.product_id).then(product => {
let data = {
product_id: item.product_id,
quantity: item.quantity,
price: product.product_details[req.body.locale].price,
price_unit: unit,
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
order.order_items.push(data)
// reduce the product stock
product.stock = Number(product.stock) - Number(item.quantity)
product.save()
item.remove()
if (index + 1 === items.length) {
order.save()
return res.json(order)
}
})
})
})
})
.catch(err => {
return res.status(500).json(err)
})
}
]
module.exports.addAddressToOrder = [
(req, res) => {
Order.findById(req.params.order_id)
.then(order => {
if (!order.address) {
User.findOne({'addresses._id': req.body.address_id})
.then(user => {
order.address = user.addresses.id(req.body.address_id)
// add processing status to order
order.statuses.push({
status: 'processing',
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
})
order.save()
return res.json(order)
})
.catch(err => {
console.log(err)
})
} else {
return res.status(500).json({message: v_m[req.body.locale].response.already_has_address})
}
})
.catch(err => {
console.log(err)
return res.status(404).json({message: v_m[req.body.locale].not_found.order_id})
})
}
]
module.exports.addStatusToOrder = [
(req, res) => {
Order.findById(req.params.order_id)
.then(order => {
order.statuses.push({
status: req.body.status,
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
})
order.save()
return res.json(order)
})
.catch(err => {
return res.status(500).json(err)
})
}
]
module.exports.getOrders = [
(req, res) => {
Order.find({user_id: req.params.user_id})
.then(orders => {
return res.json(orders)
})
.catch(err => {
return res.status(500).json(err)
})
}
]
module.exports.getOneOrder = [
(req, res) => {
Order.findById(req.params.order_id)
.then(order => {
return res.json(order)
})
.catch(err => {
return res.status(500).json(err)
})
}
]
////////////////////////////////////// get list of all orders for admin
module.exports.getAllOrders = [
(req, res) => {
Order.find({})
.then(orders => {
return res.json(orders)
})
.catch(err => {
return res.status(500).json(err)
})
}
]
+15 -273
View File
@@ -2,162 +2,36 @@ const ProductCategory = require('../models/product/ProductCategory')
const Product = require('../models/product/Product')
const {body, validationResult} = require('express-validator')
const dateformat = require('dateformat')
const jimp = require('jimp')
const fs = require('fs')
const v_m = require('../validation_messages')
module.exports.create = [
[
body('fa_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.fa.name': value})
.then(category => {
if (category) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
.notEmpty().withMessage(v_m['fa'].required.title),
body('en_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.en.name': value})
.then(category => {
if (category) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
body('de_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.de.name': value})
.then(category => {
if (category) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
body('tr_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.tr.name': value})
.then(category => {
if (category) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
body('it_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.it.name': value})
.then(category => {
if (category) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
body('fa_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('en_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('de_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('tr_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('it_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
let image
let imageName
let cover
let coverName
if (req.files) {
if (req.files.image) {
image = req.files.image
imageName = 'categoryImage_' + Date.now() + '.' + image.mimetype.split('/')[1]
if (image.mimetype.split('/')[1] !== 'png') return res.status(422).json({validation: {image: {msg: 'فرمت عکس باید png باشد.'}}})
} else {
return res.status(422).json({validation: {image: {msg: 'عکس اجباری است.'}}})
}
if (req.files.cover) {
cover = req.files.cover
coverName = 'categoryCover_' + Date.now() + '.' + cover.mimetype.split('/')[1]
if (cover.size / 1024 > 500) return res.status(422).json({validation: {cover: {msg: 'حجم کاور نباید بیشتر از 500 کیلوبایت باشد'}}})
cover.mv(`./static/uploads/images/products/category/${coverName}`)
} else {
return res.status(422).json({validation: {cover: {msg: 'کاور اجباری است.'}}})
}
} else {
return res.status(422).json({
validation: {
image: {msg: 'عکس اجباری است.'},
cover: {msg: 'کاور اجباری است.'}
}
})
}
const data = {
cover: coverName,
category_details: {
fa: {
name: req.body.fa_name,
caption: req.body.fa_caption
name: req.body.fa_name
},
en: {
name: req.body.en_name,
caption: req.body.en_caption
},
de: {
name: req.body.de_name,
caption: req.body.de_caption
},
tr: {
name: req.body.tr_name,
caption: req.body.tr_caption
},
it: {
name: req.body.it_name,
caption: req.body.it_caption
name: req.body.en_name
}
},
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
jimp.read(image.data).then(img => {
img
.cover(380, 230)
.write(`./static/uploads/images/products/category/${imageName}`, err => {
if (err) console.log(err)
data.image = imageName
const category = new ProductCategory(data)
category.save(err => {
if (err) return res.status(500).json({message: err})
return res.json({message: 'دسته بندی با موفقیت ثبت شد.'})
})
})
const category = new ProductCategory(data)
category.save(err => {
if (err) return res.status(500).json({message: err})
return res.json({message: v_m['fa'].response.success_save})
})
}
]
@@ -186,154 +60,30 @@ module.exports.getOne = [
module.exports.update = [
[
body('fa_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.fa.name': value})
.then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
.notEmpty().withMessage(v_m['fa'].required.title),
body('en_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.en.name': value})
.then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
body('de_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.de.name': value})
.then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
body('tr_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.tr.name': value})
.then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
body('it_name')
.notEmpty().withMessage('نام نباید خالی باشد.')
.bail()
.custom((value, {req}) => {
return ProductCategory.findOne({'category_details.it.name': value})
.then(category => {
if (category && category._id.toString() !== req.params.id) return Promise.reject('دسته بندی با این نام از قبل وجود دارد')
return true
})
}
),
body('fa_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('en_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('de_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('tr_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.'),
body('it_caption')
.notEmpty().withMessage('توضیحات نباید خالی باشد.')
.notEmpty().withMessage(v_m['fa'].required.title)
],
(req, res) => {
// check validation results
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
let image
let imageName
let cover
let coverName
const data = {
category_details: {
fa: {
name: req.body.fa_name,
caption: req.body.fa_caption
name: req.body.fa_name
},
en: {
name: req.body.en_name,
caption: req.body.en_caption
},
de: {
name: req.body.de_name,
caption: req.body.de_caption
},
tr: {
name: req.body.tr_name,
caption: req.body.tr_caption
},
it: {
name: req.body.it_name,
caption: req.body.it_caption
name: req.body.en_name
}
}
}
if (req.files) {
if (req.files.image) {
image = req.files.image
imageName = 'categoryImage_' + Date.now() + '.' + image.mimetype.split('/')[1]
if (image.mimetype.split('/')[1] !== 'png') return res.status(422).json({validation: {image: {msg: 'فرمت عکس باید png باشد.'}}})
data.image = imageName
jimp.read(image.data).then(img => {
img
.cover(380, 230)
.write(`./static/uploads/images/products/category/${imageName}`, err => {
if (err) console.log(err)
}
)
})
}
if (req.files.cover) {
cover = req.files.cover
coverName = 'categoryCover_' + Date.now() + '.' + cover.mimetype.split('/')[1]
if (cover.size / 1024 > 500) return res.status(422).json({validation: {cover: {msg: 'حجم کاور نباید بیشتر از 500 کیلوبایت باشد'}}})
cover.mv(`./static/uploads/images/products/category/${coverName}`)
data.cover = coverName
}
}
ProductCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) return res.status(404).json({message: err})
if (image && image.data) fs.unlink(`./static/${oldData.image}`, err => {
if (err) console.log(err)
})
if (cover && cover.data) fs.unlink(`./static/${oldData.cover}`, err => {
if (err) console.log(err)
})
ProductCategory.findById(oldData._id)
.then(category => {
return res.json(category)
})
return res.json({message: v_m['fa'].response.success_save})
})
}
]
@@ -347,15 +97,7 @@ module.exports.delete = [
else {
ProductCategory.findByIdAndDelete(req.params.id, (err, category) => {
if (err) return res.status(404).json({message: err})
if (category) {
fs.unlink(`./static/${category.image}`, err => {
if (err) console.log(err)
})
fs.unlink(`./static/${category.cover}`, err => {
if (err) console.log(err)
})
return res.json({message: 'دسته بندی حذف شد.'})
}
return res.json({message: v_m['fa'].response.success_remove})
})
}
})
+365 -298
View File
@@ -1,168 +1,207 @@
const Product = require('../models/product/Product')
const CartItem = require('../models/user/Cart_item')
const Order = require('../models/user/Order')
const {body, validationResult} = require('express-validator')
const dateformat = require('dateformat')
const jimp = require('jimp')
const fs = require('fs')
const v_m = require('../validation_messages')
////////////////////////////////////////// products controllers
module.exports.createProduct = [
[
body('fa_name')
.isLength({min: 2}).withMessage('حداقل 2 کاراکتر')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return Product.findOne({'product_details.fa.name': value})
.then(product => {
if (product) return Promise.reject('محصول با این نام از قبل وجود دارد.')
if (product) return Promise.reject(v_m['fa'].duplicated.name)
else return true
})
}),
body('en_name')
.if((value, {req}) => value !== '')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return Product.findOne({'product_details.en.name': value})
.then(product => {
if (product) return Promise.reject('محصول با این نام از قبل وجود دارد.')
if (product) return Promise.reject(v_m['fa'].duplicated.name)
else return true
})
}),
body('de_name')
.if((value, {req}) => value !== '')
.custom((value, {req}) => {
return Product.findOne({'product_details.de.name': value})
.then(product => {
if (product) return Promise.reject('محصول با این نام از قبل وجود دارد.')
else return true
})
}),
body('tr_name')
.if((value, {req}) => value !== '')
.custom((value, {req}) => {
return Product.findOne({'product_details.tr.name': value})
.then(product => {
if (product) return Promise.reject('محصول با این نام از قبل وجود دارد.')
else return true
})
}),
body('it_name')
.if((value, {req}) => value !== '')
.custom((value, {req}) => {
return Product.findOne({'product_details.it.name': value})
.then(product => {
if (product) return Promise.reject('محصول با این نام از قبل وجود دارد.')
else return true
})
}),
body('fa_description')
.isLength({min: 2}).withMessage('حداقل 2 کاراکتر'),
body('fa_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
body('fa_short_description')
.notEmpty().withMessage(v_m['fa'].required.caption)
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100),
body('en_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
body('en_short_description')
.notEmpty().withMessage(v_m['fa'].required.caption)
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100),
body('de_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
body('fa_page_title')
.notEmpty().withMessage(v_m['fa'].required.title),
body('tr_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
body('en_page_title')
.notEmpty().withMessage(v_m['fa'].required.title),
body('it_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
body('fa_page_description')
.notEmpty().withMessage(v_m['fa'].required.caption),
body('stock')
.notEmpty().withMessage('موجودی را وارد کنید.')
.bail()
.isNumeric().withMessage('موجودی باید از جنس عدد باشد'),
body('en_page_description')
.notEmpty().withMessage(v_m['fa'].required.caption),
body('en_page_description')
.notEmpty().withMessage(v_m['fa'].required.caption),
body('category')
.notEmpty().withMessage('دسته بندی را انتخاب کنید.')
.notEmpty().withMessage(v_m['fa'].required.category)
],
(req, res) => {
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
if (!req.files || !req.files.cover) return res.status(422).json({validation: {cover: {msg: v_m['fa'].required.cover}}})
let image
let imageName
if (req.files && req.files.image) {
image = req.files.image
imageName = 'product_' + Date.now() + '.' + image.mimetype.split('/')[1]
} else {
return res.status(422).json({validation: {image: {msg: 'عکس اجباری است.'}}})
let cover = 'product_' + Date.now() + '.' + req.files.cover.mimetype.split('/')[1]
let more_section_image1 = null
let more_section_image2 = null
let render_image1 = null
let render_image2 = null
let chart_image = null
//// generate files names
if (req.files) {
if (req.files.more_section_image1) {
more_section_image1 = 'product_' + Date.now() + 1 + '.' + req.files.more_section_image1.mimetype.split('/')[1]
}
if (req.files.more_section_image2) {
more_section_image2 = 'product_' + Date.now() + 2 + '.' + req.files.more_section_image2.mimetype.split('/')[1]
}
if (req.files.render_image1) {
render_image1 = 'product_' + Date.now() + 3 + '.' + req.files.render_image1.mimetype.split('/')[1]
}
if (req.files.render_image2) {
render_image2 = 'product_' + Date.now() + 4 + '.' + req.files.render_image2.mimetype.split('/')[1]
}
if (req.files.chart_image) {
chart_image = 'product_' + Date.now() + 5 + '.' + req.files.chart_image.mimetype.split('/')[1]
}
}
const data = {
price: req.body.price,
stock: req.body.stock,
cover: cover,
category: req.body.category,
more_section: req.body.more_section,
download_section: req.body.download_section,
product_details: {
fa: {
name: req.body.fa_name,
description: req.body.fa_description,
price: req.body.fa_price
short_description: req.body.fa_short_description,
page_title: req.body.fa_page_title,
page_description: req.body.fa_page_description,
more_title1: req.body.fa_more_title1,
more_description1: req.body.fa_more_description1,
more_title2: req.body.fa_more_title2,
more_description2: req.body.fa_more_description2,
render_caption1: req.body.fa_render_caption1,
render_caption2: req.body.fa_render_caption2,
chart_title: req.body.fa_chart_title,
chart_description: req.body.fa_chart_description
},
en: {
name: req.body.en_name,
description: req.body.en_description,
price: req.body.en_price
},
de: {
name: req.body.de_name,
description: req.body.de_description,
price: req.body.de_price
},
it: {
name: req.body.it_name,
description: req.body.it_description,
price: req.body.it_price
},
tr: {
name: req.body.tr_name,
description: req.body.tr_description,
price: req.body.tr_price
short_description: req.body.en_short_description,
page_title: req.body.en_page_title,
page_description: req.body.en_page_description,
more_title1: req.body.en_more_title1,
more_description1: req.body.en_more_description1,
more_title2: req.body.en_more_title2,
more_description2: req.body.en_more_description2,
render_caption1: req.body.en_render_caption1,
render_caption2: req.body.en_render_caption2,
chart_title: req.body.en_chart_title,
chart_description: req.body.en_chart_description
}
},
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
if (req.files.more_section_image1) data.more_section_image1 = more_section_image1
if (req.files.more_section_image2) data.more_section_image2 = more_section_image2
if (req.files.render_image1) data.render_image1 = render_image1
if (req.files.render_image2) data.render_image2 = render_image2
if (req.files.chart_image) data.chart_image = chart_image
jimp.read(image.data)
.then(img => {
img
.resize(250, jimp.AUTO)
.cover(250, 250)
.write(`./static/uploads/images/products/${imageName}`)
//// write to database
data.image = imageName
const product = new Product(data)
product.save((err, data) => {
if (err) console.log(err)
return res.json(data)
})
})
//// save images
if (req.files) {
if (req.files.cover) {
await jimp.read(req.files.cover.data)
.then(img => {
img
.resize(470, jimp.AUTO)
.cover(470, 390)
.quality(70)
.write(`./static/uploads/images/products/${cover}`)
})
}
if (req.files.more_section_image1) {
await jimp.read(req.files.more_section_image1.data)
.then(img => {
img
.resize(778, jimp.AUTO)
.cover(778, 395)
.quality(70)
.write(`./static/uploads/images/products/${more_section_image1}`)
})
}
if (req.files.more_section_image2) {
await jimp.read(req.files.more_section_image2.data)
.then(img => {
img
.resize(778, jimp.AUTO)
.cover(778, 395)
.quality(70)
.write(`./static/uploads/images/products/${more_section_image2}`)
})
}
if (req.files.render_image1) {
await jimp.read(req.files.render_image1.data)
.then(img => {
img
.resize(300, jimp.AUTO)
.cover(300, 300)
.quality(70)
.write(`./static/uploads/images/products/${render_image1}`)
})
}
if (req.files.render_image2) {
await jimp.read(req.files.render_image2.data)
.then(img => {
img
.resize(300, jimp.AUTO)
.cover(300, 300)
.quality(70)
.write(`./static/uploads/images/products/${render_image2}`)
})
}
if (req.files.chart_image) {
await jimp.read(req.files.chart_image.data)
.then(img => {
img
.quality(100)
.write(`./static/uploads/images/products/${chart_image}`)
})
}
}
//// write to database
const product = new Product(data)
product.save((err, data) => {
if (err) console.log(err)
return res.json(data)
})
}
]
@@ -179,7 +218,7 @@ module.exports.getAllProductsByCategory = [
module.exports.getAllProducts = [
(req, res) => {
Product.find({}).select('image stock category product_details').exec((err, products) => {
Product.find({}).select('cover category product_details').exec((err, products) => {
if (err) console.log(err)
return res.json(products)
})
@@ -198,181 +237,233 @@ module.exports.getOneProduct = [
module.exports.updateProduct = [
[
body('fa_name')
.isLength({min: 2}).withMessage('حداقل 2 کاراکتر')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return Product.findOne({'product_details.fa.name': value})
.then(product => {
if (product && product._id.toString() !== req.params.id) return Promise.reject('محصول با این نام از قبل وجود دارد.')
if (product && product._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name)
else return true
})
}),
body('en_name')
.if((value, {req}) => value !== '')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return Product.findOne({'product_details.en.name': value})
.then(product => {
if (product && product._id.toString() !== req.params.id) return Promise.reject('محصول با این نام از قبل وجود دارد.')
if (product && product._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name)
else return true
})
}),
body('de_name')
.if((value, {req}) => value !== '')
.custom((value, {req}) => {
return Product.findOne({'product_details.de.name': value})
.then(product => {
if (product && product._id.toString() !== req.params.id) return Promise.reject('محصول با این نام از قبل وجود دارد.')
else return true
})
}),
body('tr_name')
.if((value, {req}) => value !== '')
.custom((value, {req}) => {
return Product.findOne({'product_details.tr.name': value})
.then(product => {
if (product && product._id.toString() !== req.params.id) return Promise.reject('محصول با این نام از قبل وجود دارد.')
else return true
})
}),
body('it_name')
.if((value, {req}) => value !== '')
.custom((value, {req}) => {
return Product.findOne({'product_details.it.name': value})
.then(product => {
if (product && product._id.toString() !== req.params.id) return Promise.reject('محصول با این نام از قبل وجود دارد.')
else return true
})
}),
body('fa_description')
.isLength({min: 2}).withMessage('حداقل 2 کاراکتر'),
body('fa_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
body('fa_short_description')
.notEmpty().withMessage(v_m['fa'].required.caption)
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100),
body('en_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
body('en_short_description')
.notEmpty().withMessage(v_m['fa'].required.caption)
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100),
body('de_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
body('fa_page_title')
.notEmpty().withMessage(v_m['fa'].required.title),
body('tr_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
body('en_page_title')
.notEmpty().withMessage(v_m['fa'].required.title),
body('it_price')
.notEmpty().withMessage('قیمت را وارد کنید.')
.bail()
.isNumeric().withMessage('قیمت باید از جنس عدد باشد'),
body('fa_page_description')
.notEmpty().withMessage(v_m['fa'].required.caption),
body('stock')
.notEmpty().withMessage('موجودی را وارد کنید.')
.bail()
.isNumeric().withMessage('موجودی باید از جنس عدد باشد'),
body('en_page_description')
.notEmpty().withMessage(v_m['fa'].required.caption),
body('en_page_description')
.notEmpty().withMessage(v_m['fa'].required.caption),
body('category')
.notEmpty().withMessage('دسته بندی را انتخاب کنید.')
.notEmpty().withMessage(v_m['fa'].required.category)
],
(req, res) => {
async (req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
let cover = null
let more_section_image1 = null
let more_section_image2 = null
let render_image1 = null
let render_image2 = null
let chart_image = null
//// generate files names
if (req.files) {
if (req.files.cover) {
cover = 'product_' + Date.now() + '.' + req.files.cover.mimetype.split('/')[1]
}
if (req.files.more_section_image1) {
more_section_image1 = 'product_' + Date.now() + 1 + '.' + req.files.more_section_image1.mimetype.split('/')[1]
}
if (req.files.more_section_image2) {
more_section_image2 = 'product_' + Date.now() + 2 + '.' + req.files.more_section_image2.mimetype.split('/')[1]
}
if (req.files.render_image1) {
render_image1 = 'product_' + Date.now() + 3 + '.' + req.files.render_image1.mimetype.split('/')[1]
}
if (req.files.render_image2) {
render_image2 = 'product_' + Date.now() + 4 + '.' + req.files.render_image2.mimetype.split('/')[1]
}
if (req.files.chart_image) {
chart_image = 'product_' + Date.now() + 5 + '.' + req.files.chart_image.mimetype.split('/')[1]
}
}
const data = {
price: req.body.price,
stock: req.body.stock,
category: req.body.category,
more_section: req.body.more_section,
download_section: req.body.download_section,
product_details: {
fa: {
name: req.body.fa_name,
description: req.body.fa_description,
price: req.body.fa_price
short_description: req.body.fa_short_description,
page_title: req.body.fa_page_title,
page_description: req.body.fa_page_description,
more_title1: req.body.fa_more_title1,
more_description1: req.body.fa_more_description1,
more_title2: req.body.fa_more_title2,
more_description2: req.body.fa_more_description2,
render_caption1: req.body.fa_render_caption1,
render_caption2: req.body.fa_render_caption2,
chart_title: req.body.fa_chart_title,
chart_description: req.body.fa_chart_description
},
en: {
name: req.body.en_name,
description: req.body.en_description,
price: req.body.en_price
},
de: {
name: req.body.de_name,
description: req.body.de_description,
price: req.body.de_price
},
it: {
name: req.body.it_name,
description: req.body.it_description,
price: req.body.it_price
},
tr: {
name: req.body.tr_name,
description: req.body.tr_description,
price: req.body.tr_price
short_description: req.body.en_short_description,
page_title: req.body.en_page_title,
page_description: req.body.en_page_description,
more_title1: req.body.en_more_title1,
more_description1: req.body.en_more_description1,
more_title2: req.body.en_more_title2,
more_description2: req.body.en_more_description2,
render_caption1: req.body.en_render_caption1,
render_caption2: req.body.en_render_caption2,
chart_title: req.body.en_chart_title,
chart_description: req.body.en_chart_description
}
},
updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
if (req.files) {
if (req.files.cover) data.cover = cover
if (req.files.more_section_image1) data.more_section_image1 = more_section_image1
if (req.files.more_section_image2) data.more_section_image2 = more_section_image2
if (req.files.render_image1) data.render_image1 = render_image1
if (req.files.render_image2) data.render_image2 = render_image2
if (req.files.chart_image) data.chart_image = chart_image
}
let image
let imageName
if (req.files && req.files.image) {
image = req.files.image
imageName = 'product_' + Date.now() + '.' + image.mimetype.split('/')[1]
data.image = imageName
jimp.read(image.data)
.then(img => {
img
.resize(250, jimp.AUTO)
.cover(250, 250)
.write(`./static/uploads/images/products/${imageName}`)
Product.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err)
fs.unlink(`./static/${oldData.image}`, (err) => {
if (err) console.log(err)
})
return res.json({message: 'product updated.'})
//// save images
if (req.files) {
if (req.files.cover) {
await jimp.read(req.files.cover.data)
.then(img => {
img
.resize(470, jimp.AUTO)
.cover(470, 390)
.quality(70)
.write(`./static/uploads/images/products/${cover}`)
})
})
} else {
Product.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err)
return res.json({message: 'product updated.'})
})
}
if (req.files.more_section_image1) {
await jimp.read(req.files.more_section_image1.data)
.then(img => {
img
.resize(778, jimp.AUTO)
.cover(778, 395)
.quality(70)
.write(`./static/uploads/images/products/${more_section_image1}`)
})
}
if (req.files.more_section_image2) {
await jimp.read(req.files.more_section_image2.data)
.then(img => {
img
.resize(778, jimp.AUTO)
.cover(778, 395)
.quality(70)
.write(`./static/uploads/images/products/${more_section_image2}`)
})
}
if (req.files.render_image1) {
await jimp.read(req.files.render_image1.data)
.then(img => {
img
.resize(300, jimp.AUTO)
.cover(300, 300)
.quality(70)
.write(`./static/uploads/images/products/${render_image1}`)
})
}
if (req.files.render_image2) {
await jimp.read(req.files.render_image2.data)
.then(img => {
img
.resize(300, jimp.AUTO)
.cover(300, 300)
.quality(70)
.write(`./static/uploads/images/products/${render_image2}`)
})
}
if (req.files.chart_image) {
await jimp.read(req.files.chart_image.data)
.then(img => {
img
.quality(100)
.write(`./static/uploads/images/products/${chart_image}`)
})
}
}
//// write to database
Product.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err)
if (req.files) {
if (req.files.cover) fs.unlink(`./static/${oldData.cover}`, err => {
if (err) console.log(err)
})
if (req.files.more_section_image1 && oldData.more_section_image1) fs.unlink(`./static/${oldData.more_section_image1}`, err => {
if (err) console.log(err)
})
if (req.files.more_section_image2 && oldData.more_section_image2) fs.unlink(`./static/${oldData.more_section_image2}`, err => {
if (err) console.log(err)
})
if (req.files.render_image1 && oldData.render_image1) fs.unlink(`./static/${oldData.render_image1}`, err => {
if (err) console.log(err)
})
if (req.files.render_image2 && oldData.render_image2) fs.unlink(`./static/${oldData.render_image2}`, err => {
if (err) console.log(err)
})
if (req.files.chart_image && oldData.chart_image) fs.unlink(`./static/${oldData.chart_image}`, err => {
if (err) console.log(err)
})
}
Product.findById(oldData._id, (err, data) => {
if (err) console.log(err)
return res.json(data)
})
})
}
]
module.exports.deleteProduct = [
(req, res) => {
CartItem.findOne({product_id: req.params.id}, (err, item) => {
Product.findByIdAndDelete(req.params.id, (err, product) => {
if (err) console.log(err)
if (item) {
return res.status(401).json({message: 'این محصول درون سبد خرید ثبت شده و نمیتوان آن را حذف کرد.'})
} else {
Order.findOne({'order_items.product_id': req.params.id}, (err, order) => {
if (err) console.log(err)
if (order) {
return res.status(401).json({message: 'این محصول درون سفارش ثبت شده و نمیتوان آن را حذف کرد.'})
} else {
Product.findByIdAndDelete(req.params.id, (err, product) => {
if (err) console.log(err)
return res.json({message: 'محصول با موفقیت حذف شد.'})
})
}
})
}
return res.json({message: v_m['fa'].response.success_remove})
})
}
]
@@ -381,15 +472,13 @@ module.exports.deleteProduct = [
module.exports.createProductImage = [
[
body('product_id')
.notEmpty().withMessage('مشخصات محصول را وارد کنید.')
.bail()
.custom((value, {req}) => {
return Product.findById(value)
.then(product => {
return true
})
.catch(err => {
return Promise.reject('محصولی با این مشخصات وجود ندارد.')
return Promise.reject(v_m['fa'].not_found.item_id)
})
})
],
@@ -403,20 +492,17 @@ module.exports.createProductImage = [
image = req.files.image
imageName = 'productImages_' + Date.now() + '.' + image.mimetype.split('/')[1]
if (image.size / 1024 > 500) return res.status(422).json({validation: {images: {image: {msg: 'حجم عکس نباید بیشتر از 500 کیلوبایت باشد.'}}}})
jimp.read(image.data)
.then(img => {
img
.resize(250, jimp.AUTO)
.cover(250, 250)
.write(`./static/uploads/images/products/gallery/${imageName}`)
.resize(470, jimp.AUTO)
.cover(470, 390)
.write(`./static/uploads/images/products/${imageName}`)
//// write to database
Product.findById(req.body.product_id, (err, product) => {
if (err) console.log(err)
product.product_images.push({
product.images.push({
image: imageName,
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
})
@@ -426,16 +512,16 @@ module.exports.createProductImage = [
})
} else {
return res.status(422).json({validation: {images: {image: {msg: 'عکس اجباری است.'}}}})
return res.status(422).json({validation: {images: {image: {msg: v_m['fa'].required.image}}}})
}
}
]
module.exports.deleteProductImage = [
(req, res) => {
Product.findOne({'product_images._id': req.params.imageID}, (err, product) => {
Product.findOne({'images._id': req.params.imageID}, (err, product) => {
if (err) return res.status(404).json(err)
const productImage = product.product_images.id(req.params.imageID)
const productImage = product.images.id(req.params.imageID)
fs.unlink(`./static/${productImage.image}`, err => {
if (err) console.log(err)
})
@@ -449,85 +535,66 @@ module.exports.deleteProductImage = [
]
////////////////////////////////////////// products features controllers
module.exports.createProductFeature = [
module.exports.createPDF = [
[
body('fa_name')
.notEmpty().withMessage('عنوان نباید خالی باشد'),
body('en_name')
.notEmpty().withMessage('عنوان نباید خالی باشد'),
body('de_name')
.notEmpty().withMessage('عنوان نباید خالی باشد'),
body('tr_name')
.notEmpty().withMessage('عنوان نباید خالی باشد'),
body('it_name')
.notEmpty().withMessage('عنوان نباید خالی باشد'),
body('fa_value')
.notEmpty().withMessage('توضیحات نباید خالی باشد'),
body('en_value')
.notEmpty().withMessage('توضیحات نباید خالی باشد'),
body('tr_value')
.notEmpty().withMessage('توضیحات نباید خالی باشد'),
body('de_value')
.notEmpty().withMessage('توضیحات نباید خالی باشد'),
body('it_value')
.notEmpty().withMessage('توضیحات نباید خالی باشد'),
body('fa_pdf')
.notEmpty().withMessage(v_m['fa'].required.title),
body('en_pdf')
.notEmpty().withMessage(v_m['fa'].required.title),
body('product_id')
.notEmpty().withMessage('مشخصات محصول را وارد کنید.')
.bail()
.custom((value, {req}) => {
return Product.findById(value)
.then(product => {
return true
})
.catch(err => {
return Promise.reject('محصولی با این مشخصات وجود ندارد.')
return Promise.reject(v_m['fa'].not_found.item_id)
})
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: {features: errors.mapped()}})
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
if (!req.files || !req.files.pdf) return res.status(422).json({validation: {pdf: {msg: v_m['fa'].required.file}}})
let file = 'pdf_' + Date.now() + '.' + req.files.pdf.mimetype.split('/')[1]
req.files.pdf.mv(`./static/uploads/pdf/${file}`, err => {
if (err) console.log(err)
})
const data = {
fa: {
name: req.body.fa_name,
value: req.body.fa_value
},
en: {
name: req.body.en_name,
value: req.body.en_value
},
de: {
name: req.body.de_name,
value: req.body.de_value
},
tr: {
name: req.body.tr_name,
value: req.body.tr_value
},
it: {
name: req.body.it_name,
value: req.body.it_value
file: file,
pdf_details: {
fa: {
name: req.body.fa_pdf
},
en: {
name: req.body.en_pdf
}
},
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
Product.findById(req.body.product_id, (err, product) => {
if (err) console.log(err)
product.product_features.push(data)
product.pdf_files.push(data)
product.save()
return res.json(product)
})
}
]
module.exports.deleteProductFeature = [
module.exports.deletePDF = [
(req, res) => {
Product.findOne({'product_features._id': req.params.featureID}, (err, product) => {
Product.findOne({'pdf_files._id': req.params.pdfID}, (err, product) => {
if (err) return res.status(500).json({message: err})
product.product_features.id(req.params.featureID).remove()
let pdf = product.pdf_files.id(req.params.pdfID)
pdf.remove(cb => {
fs.unlink(`./static/${pdf.file}`, err => {
if (err) console.log(err)
})
})
product.save()
return res.json(product)
})
+202
View File
@@ -0,0 +1,202 @@
const Project = require('../models/Project')
const {body, validationResult} = require('express-validator')
const jimp = require('jimp')
const fs = require('fs')
const dateFormat = require('dateformat')
const v_m = require('../validation_messages')
///////////////////////////////////////// create project
module.exports.create = [
[
body('fa_name')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return Project.findOne({'project_details.fa.name': value})
.then(project => {
if (project) return Promise.reject(v_m['fa'].duplicated.name)
else return true
})
}),
body('en_name')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return Project.findOne({'project_details.en.name': value})
.then(project => {
if (project) return Promise.reject(v_m['fa'].duplicated.name)
else return true
})
}),
body('date')
.notEmpty().withMessage(v_m['fa'].required.date),
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = {
date: req.body.date,
project_details: {
fa: {
name: req.body.fa_name,
description: req.body.fa_description,
},
en: {
name: req.body.en_name,
description: req.body.en_description,
}
},
created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
const project = new Project(data)
project.save((err, project) => {
if (err) console.log(err)
return res.json(project)
})
}
]
///////////////////////////////////////// get all projects
module.exports.getAll = [
(req, res) => {
Project.find({}, (err, projects) => {
if (err) return res.json({errors: err})
return res.json(projects)
})
}
]
///////////////////////////////////////// get one project
module.exports.getOne = [
(req, res) => {
Project.findById(req.params.id, (err, project) => {
if (err) return res.json({errors: err})
return res.json(project)
})
}
]
///////////////////////////////////////// update one project
module.exports.update = [
[
body('fa_name')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return Project.findOne({'project_details.fa.name': value})
.then(project => {
if (project && project._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name)
else return true
})
}),
body('en_name')
.notEmpty().withMessage(v_m['fa'].required.title)
.bail()
.custom((value, {req}) => {
return Project.findOne({'project_details.en.name': value})
.then(project => {
if (project && project._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name)
else return true
})
}),
body('date')
.notEmpty().withMessage(v_m['fa'].required.date),
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = {
date: req.body.date,
project_details: {
fa: {
name: req.body.fa_name,
description: req.body.fa_description,
},
en: {
name: req.body.en_name,
description: req.body.en_description,
}
},
updated_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
Project.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err)
return res.json({message: v_m['fa'].response.success_save})
})
}
]
///////////////////////////////////////// delete project
module.exports.delete = [
(req, res) => {
Project.findByIdAndRemove(req.params.id, (err, data) => {
if (err) return res.json({error: err})
data.images.forEach(async item => {
await fs.unlink(`./static/${item.image}`, err => {
if (err) console.log(err)
})
})
return res.json({message: v_m['fa'].response.success_remove})
})
}
]
////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// add images to project
module.exports.addImage = [
(req, res) => {
Project.findById(req.params.id)
.then(project => {
if (!req.files || !req.files.image) return res.status(422).json({validation: {image: {msg: v_m['fa'].required.image}}})
let fileName = 'project_' + Date.now() + '.' + req.files.image.mimetype.split('/')[1]
jimp.read(req.files.image.data)
.then(img => {
img
.cover(1010, 534)
.quality(80)
.write(`./static/uploads/images/projects/${fileName}`)
////
const data = {
image: fileName,
created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
project.images.push(data)
project.save(cb => {
return res.json(project)
})
})
.catch(err => {
console.log(err)
})
})
}
]
module.exports.deleteImage = [
(req, res) => {
Project.findOne({'images._id': req.params.id}, (err, project) => {
if (err) console.log(err)
if (project) {
let image = project.images.id(req.params.id)
fs.unlink(`./static/${image.image}`, err => {
if (err) console.log(err)
image.remove()
project.save(cb => {
return res.json({message: v_m['fa'].response.success_remove})
})
})
}
})
}
]
+30 -52
View File
@@ -3,25 +3,22 @@ const dateFormat = require('dateformat')
const {body, validationResult} = require('express-validator')
const jimp = require('jimp')
const fs = require('fs')
const v_m = require('../validation_messages')
//////////////////////////////////////////////////////////////////////////////// create
module.exports.create = [
[
body('fa_title')
.isLength({max: 40}).withMessage(v_m['fa'].max_char.max40),
body('en_title')
.isLength({max: 40}).withMessage(v_m['fa'].max_char.max40),
body('fa_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.'),
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100),
body('en_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.'),
body('de_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.'),
body('tr_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.'),
body('it_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.')
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100)
],
(req, res) => {
const errors = validationResult(req)
@@ -29,9 +26,9 @@ module.exports.create = [
if (req.files) {
let file = req.files.image
let fileName = 'image_' + Date.now() + '.' + file.mimetype.split('/')[1]
jimp.read(file.data)
.then(img => {
let fileName = 'image_' + Date.now() + '.' + img.getExtension()
if (img.bitmap.width >= 1920 && img.bitmap.height >= 1080) {
if (file.size / 1024 < 450) {
file.mv(`./static/uploads/images/slider/${fileName}`, (err, img) => {
@@ -39,26 +36,19 @@ module.exports.create = [
image: fileName,
slider_details: {
fa: {
title: req.body.fa_title,
caption: req.body.fa_caption
},
en: {
title: req.body.en_title,
caption: req.body.en_caption
},
de: {
caption: req.body.de_caption
},
tr: {
caption: req.body.tr_caption
},
it: {
caption: req.body.it_caption
}
},
created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
})
slider.save((err, data) => {
if (err) return res.status(500).json({error: err})
return res.json({message: 'اسلاید اضافه شد'})
return res.json({message: v_m['fa'].response.success_save})
})
})
} else {
@@ -72,7 +62,7 @@ module.exports.create = [
console.log(err)
})
} else {
return res.status(422).json({validation: {image: {msg: 'عکس اجباری است.'}}})
return res.status(422).json({validation: {image: {msg: v_m['fa'].required.image}}})
}
}
]
@@ -91,7 +81,7 @@ module.exports.getAll = [
module.exports.getOne = [
(req, res) => {
Slider.findById(req.params.id, (err, slide) => {
if (err) return res.status(404).json({error: 'no slide with this id.'})
if (err) return res.status(404).json({error: v_m['fa'].not_found.item_id})
return res.json(slide)
})
}
@@ -100,20 +90,17 @@ module.exports.getOne = [
//////////////////////////////////////////////////////////////////////////////// update
module.exports.update = [
[
body('fa_title')
.isLength({max: 40}).withMessage(v_m['fa'].max_char.max40),
body('en_title')
.isLength({max: 40}).withMessage(v_m['fa'].max_char.max40),
body('fa_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.'),
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100),
body('en_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.'),
body('de_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.'),
body('tr_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.'),
body('it_caption')
.isLength({min: 10, max: 65}).withMessage('حداقل 10 کاراکتر و حداکثر 65 کاراکتر.')
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100)
],
(req, res) => {
const errors = validationResult(req)
@@ -122,19 +109,12 @@ module.exports.update = [
const data = {
slider_details: {
fa: {
title: req.body.fa_title,
caption: req.body.fa_caption
},
en: {
title: req.body.en_title,
caption: req.body.en_caption
},
de: {
caption: req.body.de_caption
},
tr: {
caption: req.body.tr_caption
},
it: {
caption: req.body.it_caption
}
},
updated_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
@@ -142,12 +122,10 @@ module.exports.update = [
if (req.files) {
let file = req.files.image
let fileName = 'image_' + Date.now() + '.' + file.mimetype.split('/')[1]
data.image = fileName
jimp.read(file.data)
.then(img => {
let fileName = 'image_' + Date.now() + '.' + img.getExtension()
data.image = fileName
if (img.bitmap.width >= 1920 && img.bitmap.height >= 1080) {
if (file.size / 1024 < 450) {
file.mv(`./static/uploads/images/slider/${fileName}`, (err) => {
@@ -158,7 +136,7 @@ module.exports.update = [
fs.unlink(`./static/${oldSlide.image}`, err => {
if (err) console.log(err)
})
return res.json({message: 'اسلاید آپدیت شد.'})
return res.json({message: v_m['fa'].response.success_save})
})
})
} else {
@@ -175,7 +153,7 @@ module.exports.update = [
} else {
Slider.findByIdAndUpdate(req.params.id, data, (err, oldSlide) => {
if (err) return res.status(500).json({error: err})
return res.json({message: 'اسلاید آپدیت شد.'})
return res.json({message: v_m['fa'].response.success_save})
})
}
}
@@ -189,7 +167,7 @@ module.exports.delete = [
fs.unlink(`./static/${data.image}`, err => {
if (err) console.log(err)
})
return res.json({message: 'اسلاید حذف شد'})
return res.json({message: v_m['fa'].response.success_remove})
})
}
]
-689
View File
@@ -1,689 +0,0 @@
const User = require('../models/user/User')
const v_m = require('../validation_messages')
const {body, validationResult} = require('express-validator')
const dateformat = require('dateformat')
const bcrypt = require('bcryptjs')
const crypto = require('crypto')
const jwt = require('jsonwebtoken')
const config = require('../config')
const nodemailer = require('nodemailer')
/////////////////////////////////////////////////////////////////////// register
module.exports.register = [
[
body('first_name')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.first_name
})
.bail()
.isLength({min: 2})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min2
}),
body('last_name')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.last_name
})
.bail()
.isLength({min: 2})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min2
}),
body('company_name')
.if((value, {req}) => req.body.type === 'company')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.company_name
}),
body('email_personal')
.if((value, {req}) => req.body.type === 'personal')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.email_personal
}),
body('email_personal')
.if(body('email_personal').notEmpty())
.isEmail()
.withMessage((value, {req}) => {
return v_m[req.body.locale].format.email
})
.custom((value, {req}) => {
return User.findOne({$or: [{email_personal: value}, {email_company: value}]})
.then(user => {
if (user) return Promise.reject(v_m[req.body.locale].duplicated.email)
else return true
})
}),
body('email_company')
.if((value, {req}) => req.body.type === 'company')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.email_company
})
.bail()
.isEmail()
.withMessage((value, {req}) => {
return v_m[req.body.locale].format.email
})
.custom((value, {req}) => {
return User.findOne({$or: [{email_personal: value}, {email_company: value}]})
.then(user => {
if (user) return Promise.reject(v_m[req.body.locale].duplicated.email)
else return true
})
}),
body('password')
.isLength({min: 4})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min4
}),
body('phone_number')
.isNumeric()
.withMessage((value, {req}) => {
return v_m[req.body.locale].format.phone_number
}),
body('password_confirmation')
.isLength({min: 4})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min4
})
.bail()
.custom((value, {req}) => {
if (value !== req.body.password) return Promise.reject(v_m[req.body.locale].required.password_confirmation)
else return true
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = {}
data.first_name = req.body.first_name
data.last_name = req.body.last_name
data.type = req.body.type
data.company_name = req.body.company_name
data.email_personal = req.body.email_personal
data.email_company = req.body.email_company
data.fb_id_personal = req.body.fb_id_personal
data.fb_id_company = req.body.fb_id_company
data.ig_id_personal = req.body.ig_id_personal
data.ig_id_company = req.body.ig_id_company
data.skype_id_personal = req.body.skype_id_personal
data.skype_id_company = req.body.skype_id_company
data.phone_number = req.body.phone_number
data.scope = 'user'
data.created_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
// generate activation key
let confirmation_key
crypto.randomBytes(20, async (err, hash) => {
if (err) console.log(err)
confirmation_key = hash.toString('hex')
data.confirmation_key = confirmation_key
let transporter = nodemailer.createTransport({
host: "www.rubynaturalco.com",
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: 'recovery@rubynaturalco.com',
pass: 'jd-m2?3ao?b('
},
tls: {
rejectUnauthorized: false
}
})
// send mail with defined transport object
let info = await transporter.sendMail({
from: '"Hima Co." <recovery@rubynaturalco.com>', // sender address
to: req.body.type === 'personal' ? req.body.email_personal : req.body.email_company, // list of receivers
subject: "Activation Link",
text: 'Active your account',
html: `
<h1>You just registered an account on <b style="color: #784fae;">Hima Website</b></h1>
<p>to activate your account click link below:</p>
<a href="https://www.rubynaturalco.com/en/account/activation/${confirmation_key}"
target="_blank"
style="display: inline-block;font-family: sans-serif;padding: 15px;background: #784fae;color: #fff;border-radius: 5px;margin-top: 20px;">Active Account</a>
`
})
// hash user password and done
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(req.body.password, salt, (err, hash) => {
if (err) console.log(err)
data.password = hash
const user = new User(data)
user.save(err => {
if (err) console.log(err)
return res.json({message: v_m[req.body.locale].response.success_save})
})
})
})
})
}
]
/////////////////////////////////////////////////////////////////////// active user
module.exports.activation = [
(req, res) => {
User.findOne({confirmation_key: req.params.key})
.then(user => {
if (user) {
user.confirmation_key = null
user.confirmed = true
user.save(err => {
if (err) console.log(err)
return res.json({message: v_m[req.body.locale].response.success_activation})
})
} else {
return res.status(404).json({message: v_m[req.body.locale].response.expired_activation_link})
}
})
.catch(err => {
return res.status(500).json(err)
})
}
]
/////////////////////////////////////////////////////////////////////// login
module.exports.login = [
[
body('email')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.email
})
.custom((value, {req}) => {
return User.findOne({$or: [{email_personal: value}, {email_company: value}]})
.then(user => {
if (!user) return Promise.reject(v_m[req.body.locale].not_found.user_id)
else return true
})
}),
body('password')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.password
}),
body('remember_me')
.exists()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.remember_me
})
.bail()
.isBoolean()
.withMessage((value, {req}) => {
return v_m[req.body.locale].format.boolean
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
User.findOne({$or: [{email_personal: req.body.email}, {email_company: req.body.email}]}, (err, user) => {
if (err) console.log(err)
if (!user.confirmed) return res.status(401).json({message: v_m[req.body.locale].response.email_not_confirmed})
bcrypt.compare(req.body.password, user.password, (err, isMatch) => {
if (err) console.log(err)
if (!isMatch) return res.status(422).json({validation: {password: {msg: v_m[req.body.locale].not_found.password}}})
let token
if (req.body.remember_me) token = jwt.sign({_id: user._id}, config.secretKey)
else token = jwt.sign({_id: user._id}, config.secretKey, {expiresIn: '1h'})
user.token = token
user.reset_pass_key = null
user.save(err => {
if (err) console.log(err)
})
return res.json({token: token})
})
})
}
]
/////////////////////////////////////////////////////////////////////// logout
module.exports.logout = [
(req, res) => {
const token = req.headers.authorization
if (token) {
User.findOneAndUpdate({token: token}, {token: null}, (err, oldData) => {
if (err) console.log(err)
if (oldData) return res.json({message: v_m['en'].response.logged_out})
return res.status(401).json({message: v_m['en'].response.not_logged_in})
})
} else {
return res.status(401).json({message: v_m['en'].response.not_logged_in})
}
}
]
/////////////////////////////////////////////////////////////////////// get user
module.exports.getUser = [
config.isUser,
(req, res) => {
const token = req.headers.authorization
if (token) {
jwt.verify(token, config.secretKey, (err, decoded) => {
if (err) return res.status(401).json({message: v_m['en'].response.unauthenticated})
User.findById(decoded._id).select('-password -reset_pass_key -token -confirmed -confirmation_key').exec((err, data) => {
if (err) console.log(err)
return res.json({user: data})
})
})
} else {
return res.status(401).json({message: v_m['en'].response.unauthenticated})
}
}
]
/////////////////////////////////////////////////////////////////////// reset password key generator
module.exports.resetPassKey = [
[
body('email')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.email
})
.bail()
.isEmail()
.withMessage((value, {req}) => {
return v_m[req.body.locale].format.email
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
User.findOne({$or: [{email_personal: req.body.email}, {email_company: req.body.email}]})
.then(user => {
if (user) {
let pass_token
crypto.randomBytes(20, async (err, hash) => {
if (err) console.log(err)
pass_token = hash.toString('hex')
user.reset_pass_key = pass_token
await user.save(err => {
if (err) console.log(err)
})
let transporter = nodemailer.createTransport({
host: "www.rubynaturalco.com",
port: 587,
secure: false, // true for 465, false for other ports
auth: {
user: 'recovery@rubynaturalco.com',
pass: 'jd-m2?3ao?b('
},
tls: {
rejectUnauthorized: false
}
})
// send mail with defined transport object
let info = await transporter.sendMail({
from: '"Hima Co." <recovery@rubynaturalco.com>', // sender address
to: req.body.email, // list of receivers
subject: "Reset Password Link",
text: 'Reset your password',
html: `
<h1>You asked to reset your account password on <b style="color: #784fae;">Hima Website</b></h1>
<p>to reset your password click on link blow, then enter new password:</p>
<a href="https://www.rubynaturalco.com/en/account/new-password/${pass_token}"
target="_blank"
style="display: inline-block;font-family: sans-serif;padding: 15px;background: #784fae;color: #fff;border-radius: 5px;margin-top: 20px;">Reset Password</a>
`
})
// Message sent: <b658f8ca-6296-ccf4-8306-87d57a0b4321@example.com>
return res.json({message: v_m[req.body.locale].response.recovery_link})
})
} else {
return res.status(404).json({message: v_m[req.body.locale].not_found.user_id})
}
})
.catch(err => {
return res.status(500).json(err)
})
}
]
/////////////////////////////////////////////////////////////////////// set new password
module.exports.setNewPass = [
[
body('password')
.isLength({min: 4})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min4
})
,
body('password_confirmation')
.isLength({min: 4})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min4
})
.bail()
.custom((value, {req}) => {
if (value !== req.body.password) return Promise.reject(v_m[req.body.locale].required.password_confirmation)
else return true
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
User.findOne({reset_pass_key: req.params.key})
.then(user => {
if (user) {
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(req.body.password, salt, (err, hash) => {
if (err) console.log(err)
user.password = hash
user.reset_pass_key = null
user.save(err => {
if (err) console.log(err)
})
return res.json({message: v_m[req.body.locale].response.success_save})
})
})
} else {
return res.status(404).json({message: v_m[req.body.locale].response.expired_reset_link})
}
})
.catch(err => {
return res.status(500).json(err)
})
}
]
/////////////////////////////////////////////////////////////////////// update user
module.exports.updateUser = [
[
body('first_name')
.isLength({min: 2})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min2
}),
body('last_name')
.isLength({min: 2})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min2
}),
body('email_personal')
.if((value, {req}) => req.body.type === 'personal')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.email_personal
}),
body('email_personal')
.if(body('email_personal').notEmpty())
.isEmail()
.withMessage((value, {req}) => {
return v_m[req.body.locale].format.email
}),
body('phone_number')
.isNumeric()
.withMessage((value, {req}) => {
return v_m[req.body.locale].format.phone_number
}),
body('email_company')
.if((value, {req}) => req.body.type === 'company')
.notEmpty()
.withMessage((value, {req}) => {
return v_m[req.body.locale].required.email_company
})
.bail()
.isEmail()
.withMessage((value, {req}) => {
return v_m[req.body.locale].format.email
}),
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const token = req.headers.authorization
const data = {}
data.first_name = req.body.first_name
data.last_name = req.body.last_name
data.email_personal = req.body.email_personal
data.fb_id_personal = req.body.fb_id_personal
data.ig_id_personal = req.body.ig_id_personal
data.skype_id_personal = req.body.skype_id_personal
data.phone_number = req.body.phone_number
data.updated_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
if (req.body.type === 'company') {
data.skype_id_company = req.body.skype_id_company
data.ig_id_company = req.body.ig_id_company
data.fb_id_company = req.body.fb_id_company
data.email_company = req.body.email_company
data.company_name = req.body.company_name
}
User.findOneAndUpdate({token: token}, data)
.then(user => {
return res.json({message: v_m[req.body.locale].response.success_save})
})
.catch(err => {
return res.status(401).json({message: v_m[req.body.locale].response.unauthenticated})
})
}
]
/////////////////////////////////////////////////////////////////////// update user password
module.exports.updateUserPassword = [
[
body('password')
.isLength({min: 4})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min4
}),
body('password_confirmation')
.isLength({min: 4})
.withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min4
})
.bail()
.custom((value, {req}) => {
if (value !== req.body.password) return Promise.reject(v_m[req.body.locale].required.password_confirmation)
else return true
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const token = req.headers.authorization
User.findOne({token: token})
.then(user => {
bcrypt.genSalt(10, (err, salt) => {
if (err) console.log(err)
bcrypt.hash(req.body.password, salt, (err, hash) => {
if (err) console.log(err)
user.password = hash
user.token = null
user.save(err => {
if (err) console.log(err)
return res.json({message: v_m[req.body.locale].response.success_save})
})
})
})
})
.catch(err => {
return res.status(404).json(err)
})
}
]
/////////////////////////////////////////////////////////////////////// addresses
module.exports.addAdress = [
[
body('user_id')
.custom((value, {req}) => {
return User.findById(value)
.then(user => {
return true
})
.catch(err => {
return Promise.reject(v_m[req.body.locale].not_found.user_id)
})
}),
body('country')
.if(body('country').isEmpty())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].required.country)
}),
body('province')
.if(body('province').isEmpty())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].required.province)
}),
body('city')
.if(body('city').isEmpty())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].required.city)
}),
body('address')
.if(body('address').isEmpty())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].required.address)
}),
body('postal_code')
.if(body('postal_code').isEmpty())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].required.postal_code)
}),
body('plaque')
.if(body('plaque').isEmpty())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].required.plaque)
}),
body('receiver_first_name')
.if(body('receiver_first_name').isEmpty())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].required.receiver_first_name)
}),
body('receiver_last_name')
.if(body('receiver_last_name').isEmpty())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].required.receiver_last_name)
}),
body('receiver_mobile')
.if(body('receiver_mobile').isEmpty())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].required.receiver_mobile)
}),
body('receiver_mobile')
.if(body('receiver_mobile').notEmpty())
.if(body('receiver_mobile').not().isNumeric())
.custom((value, {req}) => {
return Promise.reject(v_m[req.body.locale].format.phone_number)
})
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = {
country: req.body.country,
province: req.body.province,
city: req.body.city,
address: req.body.address,
postal_code: req.body.postal_code,
plaque: req.body.plaque,
block_number: req.body.block_number,
receiver_first_name: req.body.receiver_first_name,
receiver_last_name: req.body.receiver_last_name,
receiver_mobile: req.body.receiver_mobile,
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}
User.findById(req.body.user_id)
.then(user => {
user.addresses.push(data)
user.save()
return res.json(user.addresses)
})
.catch(err => {
console.log(err)
})
}
]
module.exports.getAddresses = [
(req, res) => {
User.findById(req.params.user_id)
.then(user => {
return res.json(user.addresses)
})
.catch(err => {
return res.status(404).json({message: v_m['en'].not_found.user_id})
})
}
]
module.exports.deleteAddress = [
(req, res) => {
User.findOne({'addresses._id': req.params.address_id})
.then(user => {
user.addresses.id(req.params.address_id).remove()
user.save()
return res.json({message: v_m['en'].response.success_remove})
})
.catch(err => {
console.log(err)
})
}
]
/////////////////////////////////////////////////////////////////////// get list of users by admin
module.exports.getAllUsers = [
(req, res) => {
User.find({confirmed: true}).select('-token -password -scope -reset_pass_key -confirmed -confirmation_key').exec((err, users) => {
if (err) console.log(err)
return res.json(users)
})
}
]
module.exports.getOneUser = [
(req, res) => {
User.findById(req.params.user_id).select('-token -password -scope -reset_pass_key -confirmed -confirmation_key').exec((err, user) => {
if (err) return res.status(404).json(err)
return res.json(user)
})
}
]
+1 -1
View File
@@ -1,6 +1,6 @@
const mongoose = require('mongoose');
// mongodb database connection string. change it as per your needs. here "mydb" is the name of the database. You don't need to create DB from mongodb terminal. mongoose create the db automatically.
mongoose.connect('mongodb://localhost:27017/hima', {
mongoose.connect('mongodb://localhost:27017/arakrail', {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
-5
View File
@@ -2,7 +2,6 @@ const express = require('express')
const db = require('./db')
const fileUpload = require('express-fileupload')
const config = require('./config')
const cron_jobs = require('./cron_jobs')
// Create express instnace
const app = express()
@@ -15,17 +14,13 @@ app.use(fileUpload())
// Require & Import API routes
const Private = require('./routes/private')
const Public = require('./routes/public')
const user = require('./routes/user')
const auth = require('./routes/auth')
// Use API Routes
app.use('/private', config.isAdmin, Private)
app.use('/user', config.isUser, user)
app.use('/auth', auth)
app.use('/public', Public)
// add cron jobs checker
cron_jobs()
// Export the server middleware
module.exports = {
-92
View File
@@ -1,92 +0,0 @@
const mongoose = require('mongoose')
function image(img) {
return '/uploads/images/about/' + img
}
const AboutPageSchema = mongoose.Schema({
aboutPage_details: {
fa: {
page_title: String,
s1_title: String,
s1_caption: String,
s2_title: String,
s2_caption: String,
s2_imageCaption: String,
s3_title: String,
s3_caption: String,
s3_imageCaption: String,
s4_text: String,
last_section_title: String,
last_section_text: String
},
en: {
page_title: String,
s1_title: String,
s1_caption: String,
s2_title: String,
s2_caption: String,
s2_imageCaption: String,
s3_title: String,
s3_caption: String,
s3_imageCaption: String,
s4_text: String,
last_section_title: String,
last_section_text: String
},
de: {
page_title: String,
s1_title: String,
s1_caption: String,
s2_title: String,
s2_caption: String,
s2_imageCaption: String,
s3_title: String,
s3_caption: String,
s3_imageCaption: String,
s4_text: String,
last_section_title: String,
last_section_text: String
},
tr: {
page_title: String,
s1_title: String,
s1_caption: String,
s2_title: String,
s2_caption: String,
s2_imageCaption: String,
s3_title: String,
s3_caption: String,
s3_imageCaption: String,
s4_text: String,
last_section_title: String,
last_section_text: String
},
it: {
page_title: String,
s1_title: String,
s1_caption: String,
s2_title: String,
s2_caption: String,
s2_imageCaption: String,
s3_title: String,
s3_caption: String,
s3_imageCaption: String,
s4_text: String,
last_section_title: String,
last_section_text: String
}
},
page_hero: {type: String, get: image},
s2_image: {type: String, get: image},
s3_image: {type: String, get: image},
last_section_image: {type: String, get: image},
created_at: String,
updated_at: String
}, {
toObject: {getters: true},
toJSON: {getters: true}
})
module.exports = mongoose.model('AboutPageContent', AboutPageSchema)
-13
View File
@@ -1,13 +0,0 @@
const mongoose = require('mongoose')
const BroadcastSchema = mongoose.Schema({
title: String,
message: String,
read: Array,
locale: String,
admin_id: String,
created_at: String
})
module.exports = mongoose.model('Broadcast', BroadcastSchema)
+1 -1
View File
@@ -6,7 +6,7 @@ const ContactPageMessageSchema = mongoose.Schema({
phone_number: String,
email: String,
message: String,
user_id: String,
reason: String,
read: {type: Boolean, default: false},
created_at: String
})
+15
View File
@@ -0,0 +1,15 @@
const mongoose = require('mongoose')
const ReasonSchema = mongoose.Schema({
reason_details: {
fa: {
reason: String
},
en: {
reason: String
}
},
created_at: String
})
module.exports = mongoose.model('ContactUsReason', ReasonSchema)
-19
View File
@@ -1,19 +0,0 @@
const mongoose = require('mongoose')
function image(file) {
return `/uploads/images/gallery/${file}`
}
const gallerySchema = mongoose.Schema({
image: {type: String, get: image},
created_at: String
}, {
toObject: {getters: true},
toJSON: {getters: true}
})
gallerySchema.virtual('thumb').get(function () {
return '/uploads/images/gallery/thumb/thumb_' + this.image.split('gallery/')[1]
})
module.exports = mongoose.model('Gallery', gallerySchema)
+15
View File
@@ -0,0 +1,15 @@
const mongoose = require('mongoose')
function catalog(pdf) {
return '/uploads/pdf/' + pdf
}
const MainCatalogSchema = mongoose.Schema({
file: {type: String, get: catalog},
created_at: String
}, {
toObject: {getters: true},
toJSON: {getters: true}
})
module.exports = mongoose.model('MainCatalog', MainCatalogSchema)
+33
View File
@@ -0,0 +1,33 @@
const mongoose = require('mongoose')
function image(file) {
return `/uploads/images/projects/${file}`
}
const ImagesSchema = mongoose.Schema({
image: {type: String, get: image},
created_at: String
}, {
toObject: {getters: true},
toJSON: {getters: true}
})
const ProjectSchema = mongoose.Schema({
images: [ImagesSchema],
project_details: {
fa: {
name: String,
description: String
},
en: {
name: String,
description: String
}
},
date: String,
created_at: String,
updated_at: String
})
module.exports = mongoose.model('Project', ProjectSchema)
+2 -9
View File
@@ -8,18 +8,11 @@ const SliderSchema = mongoose.Schema({
image: {type: String, get: image},
slider_details: {
fa: {
title: String,
caption: String
},
en: {
caption: String
},
de: {
caption: String
},
tr: {
caption: String
},
it: {
title: String,
caption: String
}
},
+1 -2
View File
@@ -4,10 +4,9 @@ const AdminSchema = mongoose.Schema({
name: String,
username: String,
password: String,
roles: Array,
created_at: String,
updated_at: String,
scope: String,
scope: {type: String, default: 'admin'},
token: String
})
-9
View File
@@ -7,15 +7,6 @@ const BlogCategorySchema = mongoose.Schema({
},
en: {
name: String
},
de: {
name: String
},
tr: {
name: String
},
it: {
name: String
}
},
created_at: String,
-15
View File
@@ -18,21 +18,6 @@ const BlogPostSchema = mongoose.Schema({
title: String,
description: String,
short_description: String
},
de: {
title: String,
description: String,
short_description: String
},
tr: {
title: String,
description: String,
short_description: String
},
it: {
title: String,
description: String,
short_description: String
}
},
created_at: String,
+49 -64
View File
@@ -4,37 +4,28 @@ function productImage(img) {
return '/uploads/images/products/' + img
}
function ProductImageGallery(img) {
return '/uploads/images/products/gallery/' + img
function productPDF(file) {
return '/uploads/pdf/' + file
}
const ProductFeatureSchema = mongoose.Schema({
fa: {
name: String,
value: String
},
en: {
name: String,
value: String
},
de: {
name: String,
value: String
},
tr: {
name: String,
value: String
},
it: {
name: String,
value: String
},
const ProductImageSchema = mongoose.Schema({
image: {type: String, get: productImage},
created_at: String
}, {
toObject: {getters: true},
toJSON: {getters: true}
})
const ProductImageSchema = mongoose.Schema({
image: {type: String, get: ProductImageGallery},
const ProductPDFSchema = mongoose.Schema({
file: {type: String, get: productPDF},
pdf_details: {
fa: {
name: String
},
en: {
name: String
}
},
created_at: String
}, {
toObject: {getters: true},
@@ -42,53 +33,47 @@ const ProductImageSchema = mongoose.Schema({
})
const ProductSchema = mongoose.Schema({
image: {type: String, get: productImage},
stock: Number,
cover: {type: String, get: productImage},
images: [ProductImageSchema],
more_section_image1: {type: String, get: productImage},
more_section_image2: {type: String, get: productImage},
render_image1: {type: String, get: productImage},
render_image2: {type: String, get: productImage},
chart_image: {type: String, get: productImage},
pdf_files: [ProductPDFSchema],
category: String,
more_section: {type: Boolean, default: true},
download_section: {type: Boolean, default: true},
product_details: {
fa: {
name: String,
description: String,
price: {
type: Number,
default: 0
}
short_description: String,
page_title: String,
page_description: String,
more_title1: String,
more_description1: String,
more_title2: String,
more_description2: String,
render_caption1: String,
render_caption2: String,
chart_title: String,
chart_description: String
},
en: {
name: String,
description: String,
price: {
type: Number,
default: 0
}
},
de: {
name: String,
description: String,
price: {
type: Number,
default: 0
}
},
it: {
name: String,
description: String,
price: {
type: Number,
default: 0
}
},
tr: {
name: String,
description: String,
price: {
type: Number,
default: 0
}
short_description: String,
page_title: String,
page_description: String,
more_title1: String,
more_description1: String,
more_title2: String,
more_description2: String,
render_caption1: String,
render_caption2: String,
chart_title: String,
chart_description: String
}
},
product_features: [ProductFeatureSchema],
product_images: [ProductImageSchema],
created_at: String,
updated_at: String
}, {
+2 -25
View File
@@ -1,39 +1,16 @@
const mongoose = require('mongoose')
function image(img) {
return '/uploads/images/products/category/' + img
}
const ProductCategorySchema = mongoose.Schema({
image: {type: String, get: image},
cover: {type: String, get: image},
category_details: {
fa: {
name: String,
caption: String
name: String
},
en: {
name: String,
caption: String
},
de: {
name: String,
caption: String
},
tr: {
name: String,
caption: String
},
it: {
name: String,
caption: String
name: String
}
},
created_at: String,
updated_at: String
}, {
toObject: {getters: true},
toJSON: {getters: true}
})
module.exports = mongoose.model('ProductCategory', ProductCategorySchema)
-11
View File
@@ -1,11 +0,0 @@
const mongoose = require('mongoose')
const Cart_ItemSchema = mongoose.Schema({
user_id: String,
product_id: String,
quantity: String,
created_at: String,
updated_at: String
})
module.exports = mongoose.model('Cart_Item', Cart_ItemSchema)
-30
View File
@@ -1,30 +0,0 @@
const mongoose = require('mongoose')
const StatusSchema = mongoose.Schema({
status: {
type: String,
enum: ['incomplete','processing', 'packing', 'sent','delivered'],
default: 'processing'
},
created_at: String
})
const Order_itemsSchema = mongoose.Schema({
product_id: String,
quantity: Number,
price: Number,
price_unit: String,
created_at: String
})
const OrderSchema = mongoose.Schema({
user_id: String,
number: Number,
address: Object,
statuses: [StatusSchema],
order_items: [Order_itemsSchema],
created_at: String,
updated_at: String
})
module.exports = mongoose.model('Order', OrderSchema)
-43
View File
@@ -1,43 +0,0 @@
const mongoose = require('mongoose')
const AddressSchema = mongoose.Schema({
country: String,
province: String,
city: String,
address: String,
postal_code: String,
plaque: String,
block_number: String,
receiver_first_name: String,
receiver_last_name: String,
receiver_mobile: String,
created_at: String
})
const UserSchema = mongoose.Schema({
first_name: String,
last_name: String,
type: {type: String, enum: ['personal', 'company'], default: 'personal'},
company_name: String,
email_personal: String,
email_company: String,
fb_id_personal: String,
fb_id_company: String,
ig_id_personal: String,
ig_id_company: String,
skype_id_personal: String,
skype_id_company: String,
addresses: [AddressSchema],
phone_number: String,
password: String,
confirmed: {type: Boolean, default: false},
confirmation_key: String,
scope: String,
token: String,
reset_pass_key: String,
created_at: String,
updated_at: String
})
module.exports = mongoose.model('User', UserSchema)
+1 -10
View File
@@ -1,21 +1,12 @@
const {Router} = require('express')
const router = Router()
const adminController = require('../controllers/adminController')
const userController = require('../controllers/userController')
////////////////////// admin routes
router.post('/admin/register', adminController.register)
// router.post('/admin/register', adminController.register)
router.post('/admin/login', adminController.login)
router.post('/admin/logout', adminController.logout)
router.get('/admin/user', adminController.getUser)
////////////////////// user routes
router.post('/user/register', userController.register)
router.post('/user/login', userController.login)
router.post('/user/logout', userController.logout)
router.get('/user/user', userController.getUser)
module.exports = router
+18 -28
View File
@@ -2,16 +2,14 @@ const {Router} = require('express')
const router = Router()
/////////////////////////////////////////////////////////// controllers
const sliderController = require('../controllers/sliderController')
const aboutPageContent_controller = require('../controllers/aboutPageContent_controller')
const productController = require('../controllers/productController')
const productCategoryController = require('../controllers/productCategoryController')
const blogCategoryController = require('../controllers/blogCategoryController')
const blogPostController = require('../controllers/blogPostController')
const userController = require('../controllers/userController')
const orderController = require('../controllers/orderController')
const galleryController = require('../controllers/galleryController')
const projectController = require('../controllers/projectController')
const contactPageController = require('../controllers/contactPageController')
const broadcastController = require('../controllers/broadcastController')
const contactUsReasonController = require('../controllers/contactUsReasonController')
const mainCatalogController = require('../controllers/mainCatalogController')
/////////////////////////////////////////////////////////// routes
//////////////// slider
@@ -19,9 +17,6 @@ router.post('/slider', sliderController.create)
router.put('/slider/:id', sliderController.update)
router.delete('/slider/:id', sliderController.delete)
//////////////// about page content
router.post('/aboutPage', aboutPageContent_controller.create)
//////////////// blog categories
router.post('/blogCategories', blogCategoryController.create)
router.put('/blogCategories/:id', blogCategoryController.update)
@@ -46,31 +41,26 @@ router.delete('/products/:id', productController.deleteProduct)
router.post('/productImage', productController.createProductImage)
router.delete('/productImage/:imageID', productController.deleteProductImage)
// product feature
router.post('/productFeature', productController.createProductFeature)
router.delete('/productFeature/:featureID', productController.deleteProductFeature)
// product PDF
router.post('/productPDF', productController.createPDF)
router.delete('/productPDF/:pdfID', productController.deletePDF)
//////////////// users
router.get('/customers', userController.getAllUsers)
router.get('/customers/:user_id', userController.getOneUser)
// user orders
router.get('/orders', orderController.getAllOrders)
router.get('/orders/:user_id', orderController.getOrders)
router.get('/order/:order_id', orderController.getOneOrder)
router.post('/addStatusToOrder/:order_id', orderController.addStatusToOrder)
//////////////// gallery
router.post('/gallery', galleryController.create)
router.delete('/gallery/:id', galleryController.delete)
//////////////// projects
router.post('/projects', projectController.create)
router.put('/projects/:id', projectController.update)
router.delete('/projects/:id', projectController.delete)
// add images
router.post('/projects/images/:id', projectController.addImage)
router.delete('/projects/images/:id', projectController.deleteImage)
//////////////// contact us
router.get('/contact', contactPageController.getAll)
router.get('/contact/:id', contactPageController.getOne)
/// contact us reason
router.post('/contact/reason', contactUsReasonController.create)
router.delete('/contact/reason/:id', contactUsReasonController.delete)
//////////////// broadcast
router.post('/broadcast', broadcastController.create)
router.get('/broadcast', broadcastController.getAll)
router.delete('/broadcast/:id', broadcastController.delete)
///////////////// main catalog
router.post('/catalog', mainCatalogController.create)
module.exports = router
+11 -24
View File
@@ -3,35 +3,20 @@ const router = Router()
/////////////////////////////////////////////////////////// controllers
const sliderController = require('../controllers/sliderController')
const localeController = require('../controllers/localeController')
const aboutPageContent_controller = require('../controllers/aboutPageContent_controller')
const productController = require('../controllers/productController')
const productCategoryController = require('../controllers/productCategoryController')
const blogCategoryController = require('../controllers/blogCategoryController')
const blogPostController = require('../controllers/blogPostController')
const galleryController = require('../controllers/galleryController')
const projectController = require('../controllers/projectController')
const contactPageController = require('../controllers/contactPageController')
const userController = require('../controllers/userController')
const contactUsReasonController = require('../controllers/contactUsReasonController')
const mainCatalogController = require('../controllers/mainCatalogController')
/////////////////////////////////////////////////////////// routes
//////////////// locale
router.get('/locale', localeController.get)
//////////////// active user account
router.post('/activeUser/:key', userController.activation)
//////////////// reset pass
router.post('/resetPass', userController.resetPassKey)
router.post('/setNewPass/:key', userController.setNewPass)
//////////////// slider
router.get('/slider', sliderController.getAll)
router.get('/slider/:id', sliderController.getOne)
//////////////// about page content
router.get('/aboutPage', aboutPageContent_controller.get)
//////////////// blog category
router.get('/blogCategories', blogCategoryController.getAll)
router.get('/blogCategories/:id', blogCategoryController.getOne)
@@ -49,14 +34,16 @@ router.get('/products/:category', productController.getAllProductsByCategory)
router.get('/products/', productController.getAllProducts)
router.get('/product/:id', productController.getOneProduct)
//////////////// gallery
router.get('/gallery', galleryController.getAll)
router.get('/gallery/:id', galleryController.getOne)
// //////////////// subscribers
// router.post('/subscribers',subscribersController.create)
//////////////// projects
router.get('/projects', projectController.getAll)
router.get('/projects/:id', projectController.getOne)
//////////////// contact us
router.post('/contact', contactPageController.create)
/// contact us reason
router.get('/contact/reason', contactUsReasonController.getAll)
//////////////// main catalog
router.get('/catalog', mainCatalogController.get)
module.exports = router
-33
View File
@@ -1,33 +0,0 @@
const {Router} = require('express')
const router = Router()
const orderController = require('../controllers/orderController')
const userController = require('../controllers/userController')
const broadcastController = require('../controllers/broadcastController')
// cart
router.post('/addToCart', orderController.addToCart)
router.put('/updateCart/:item_id', orderController.updateCart)
router.get('/cartItems/:user_id', orderController.getCartItems)
router.delete('/deleteItem/:item_id', orderController.deleteFromCart)
// order
router.post('/addOrder', orderController.addOrder)
router.post('/addAddressToOrder/:order_id', orderController.addAddressToOrder)
router.get('/orders/:user_id', orderController.getOrders)
router.get('/order/:order_id', orderController.getOneOrder)
// address
router.post('/addAddress', userController.addAdress)
router.delete('/addresses/:address_id', userController.deleteAddress)
router.get('/addresses/:user_id', userController.getAddresses)
// update profile
router.put('/profile', userController.updateUser)
router.post('/password', userController.updateUserPassword)
// broadcast
router.get('/broadcast', broadcastController.getAll)
router.post('/broadcast/:id', broadcastController.getOne)
module.exports = router
+111 -16
View File
@@ -4,6 +4,7 @@ module.exports = {
// developer validations
remember_me: 'پارامتر remember_me الزامی است',
// registration validations
name: 'نام را وارد کنید',
first_name: 'نام را وارد کنید',
last_name: 'نام خانوادگی را وارد کنید',
email: 'ایمیل را وارد کنید',
@@ -13,7 +14,6 @@ module.exports = {
username: 'نام کاربری را وارد کنید',
phone_number: 'شماره تماس را وارد کنید',
password: 'پسورد را وارد کنید',
password_confirmation: 'پسورد ها یکی نیست',
// addressing validations
country: 'کشور را وارد کنید',
province: 'استان را وارد کنید',
@@ -31,8 +31,11 @@ module.exports = {
category: 'دسته بندی را انتخاب کنید',
image: 'عکس اجباری است',
cover: 'کاور اجباری است',
file: 'فایل اجباری است',
message: 'پیام را بنویسید',
quantity: 'تعداد را وارد کنید'
quantity: 'تعداد را وارد کنید',
date: 'تاریخ را وارد کنید',
reason: 'دلیل را انتخاب کنید'
},
format: {
phone_number: 'فرمت شماره تماس صحیح نیست',
@@ -102,7 +105,23 @@ module.exports = {
expired_reset_link: 'این لینک بازیابی منقضی شده است',
email_not_confirmed: 'ابتدا ایمیل خود را تایید کنید،لینک فعال سازی قبلا برای شما فرستاده شده است.',
expired_activation_link: 'این لینک فعال سازی منقضی شده است',
success_activation: 'اکانت شما با موفقیت فعال شد'
success_activation: 'اکانت شما با موفقیت فعال شد',
passwords_not_match: 'پسورد ها یکی نیست',
},
file_types: {
jpg: 'فقط فرمت jpg قابل قبول است',
png: 'فقط فرمت png قابل قبول است',
gif: 'فقط فرمت gif قابل قبول است',
pdf: 'فقط فرمت pdf قابل قبول است',
txt: 'فقط فرمت txt قابل قبول است',
log: 'فقط فرمت log قابل قبول است',
mp3: 'فقط فرمت mp3 قابل قبول است',
ogg: 'فقط فرمت ogg قابل قبول است',
wmv: 'فقط فرمت wmv قابل قبول است',
mp4: 'فقط فرمت mp4 قابل قبول است',
mov: 'فقط فرمت mov قابل قبول است',
mkv: 'فقط فرمت mkv قابل قبول است',
flv: 'فقط فرمت flv قابل قبول است'
}
},
en: {
@@ -110,7 +129,8 @@ module.exports = {
// developer validations
remember_me: 'Remember_me parameter required',
// registration validations
first_name: 'Enter name',
name: 'Enter name',
first_name: 'Enter first name',
last_name: 'Enter last name',
email: 'Enter email',
email_personal: 'Personal email is required',
@@ -119,7 +139,6 @@ module.exports = {
username: 'Enter username',
phone_number: 'Enter phone number',
password: 'Enter password',
password_confirmation: 'Passwords are not the same',
// addressing validations
country: 'Enter country',
province: 'Enter province',
@@ -137,8 +156,11 @@ module.exports = {
category: 'Select category',
image: 'Image is required',
cover: 'Cover is required',
file: 'File is required',
message: 'Write message',
quantity: 'Enter quantity'
quantity: 'Enter quantity',
date: 'Enter date',
reason: 'Select reason'
},
format: {
phone_number: 'Phone number format in incorrect',
@@ -208,7 +230,23 @@ module.exports = {
expired_reset_link: 'The current reset pass link has been expired',
email_not_confirmed: 'Confirm your email first, the activation link has already been sent to you.',
expired_activation_link: 'This activation link has expired',
success_activation: 'Your account has been successfully activated'
success_activation: 'Your account has been successfully activated',
passwords_not_match: 'Passwords are not the same',
},
file_types: {
jpg: 'Only jpg format is acceptable',
png: 'Only png format is acceptable',
gif: 'Only gif format is acceptable',
pdf: 'Only pdf format is acceptable',
txt: 'Only txt format is acceptable',
log: 'Only log format is acceptable',
mp3: 'Only mp3 format is acceptable',
ogg: 'Only ogg format is acceptable',
wmv: 'Only wmv format is acceptable',
mp4: 'Only mp4 format is acceptable',
mov: 'Only mov format is acceptable',
mkv: 'Only mkv format is acceptable',
flv: 'Only flv format is acceptable'
}
},
de: {
@@ -216,6 +254,7 @@ module.exports = {
// developer validations
remember_me: 'Remember_me-Parameter erforderlich',
// registration validations
name: 'Name eingeben',
first_name: 'Name eingeben',
last_name: 'Nachnamen eingeben',
email: 'Email eingeben',
@@ -225,7 +264,6 @@ module.exports = {
username: 'Geben Sie den Benutzernamen ein',
phone_number: 'Telefonnummer eingeben',
password: 'Passwort eingeben',
password_confirmation: 'Passwörter sind nicht dasselbe',
// addressing validations
country: 'Land eingeben',
province: 'Stadt betreten',
@@ -243,8 +281,11 @@ module.exports = {
category: 'Kategorie wählen',
image: 'Bild ist erforderlich',
cover: 'Bild ist erforderlich Abdeckung ist erforderlich',
file: 'Datei ist erforderlich',
message: 'Nachricht schreiben',
quantity: 'Menge eingeben'
quantity: 'Menge eingeben',
date: 'Enter date',
reason: 'Grund auswählen'
},
format: {
phone_number: 'Telefonnummernformat falsch',
@@ -314,7 +355,23 @@ module.exports = {
expired_reset_link: 'Der aktuelle Reset-Pass-Link ist abgelaufen',
email_not_confirmed: "Bestätigen Sie zuerst Ihre E-Mail, der Aktivierungslink wurde bereits an Sie gesendet.",
expired_activation_link: 'Dieser Aktivierungslink ist abgelaufen',
success_activation: 'Ihr Konto wurde erfolgreich aktiviert'
success_activation: 'Ihr Konto wurde erfolgreich aktiviert',
passwords_not_match: 'Passwörter sind nicht dasselbe'
},
file_types: {
jpg: 'Nur das jpg-Format ist akzeptabel',
png: 'Nur das png-Format ist akzeptabel',
gif: 'Nur das gif-Format ist akzeptabel',
pdf: 'Nur das PDF-Format ist akzeptabel',
txt: 'Nur das txt-Format ist akzeptabel',
log: 'Nur das log-Format ist akzeptabel',
mp3: 'Nur das mp3-Format ist akzeptabel',
ogg: 'Nur das ogg-Format ist akzeptabel',
wmv: 'Nur das wmv-Format ist akzeptabel',
mp4: 'Nur das mp4-Format ist akzeptabel',
mov: 'Nur das mov-Format ist akzeptabel',
mkv: 'Nur das mkv-Format ist akzeptabel',
flv: 'Nur das flv-Format ist akzeptabel'
}
},
tr: {
@@ -322,6 +379,7 @@ module.exports = {
// geliştirici doğrulamaları
Remember_me: 'Remember_me parametresi gerekli',
// kayıt doğrulamaları
name: 'Adı girin',
first_name: 'Adı girin',
last_name: 'Soyadı girin',
email: 'E-posta girin',
@@ -331,7 +389,6 @@ module.exports = {
username: 'Kullanıcı adını girin',
phone_number: 'Telefon numarasını girin',
password: 'Şifre girin',
password_confirmation: 'Şifreler aynı değil',
// doğrulamaları adresleme
country: 'Ülke girin',
province: 'İl girin',
@@ -349,8 +406,11 @@ module.exports = {
category: 'Kategori seçin',
image: 'Resim gerekli',
cover: 'Kapak gereklidir',
file: 'Dosya gerekli',
message: 'Mesaj yaz',
quantity: 'Miktar girin'
quantity: 'Miktar girin',
date: 'Enter date',
reason: 'Nedeni seçin'
},
format: {
phone_number: 'Telefon numarası biçimi yanlış',
@@ -420,7 +480,23 @@ module.exports = {
expired_reset_link: 'Mevcut sıfırlama geçiş bağlantısının süresi doldu',
email_not_confirmed: 'Önce e-postanızı onaylayın, aktivasyon bağlantısı size zaten gönderildi.',
expired_activation_link: "Bu aktivasyon bağlantısının süresi doldu",
success_activation: 'Hesabınız başarıyla etkinleştirildi'
success_activation: 'Hesabınız başarıyla etkinleştirildi',
passwords_not_match: 'Şifreler aynı değil'
},
file_types: {
jpg: 'Yalnızca jpg formatı kabul edilebilir',
png: 'Sadece png formatı kabul edilebilir',
gif: 'Yalnızca gif formatı kabul edilebilir',
pdf: 'Yalnızca pdf formatı kabul edilebilir',
txt: 'Yalnızca txt formatı kabul edilebilir',
log: 'Yalnızca log formatı kabul edilebilir',
mp3: 'Yalnızca mp3 formatı kabul edilebilir',
ogg: 'Yalnızca ogg formatı kabul edilebilir',
wmv: 'Yalnızca wmv formatı kabul edilebilir',
mp4: 'Yalnızca mp4 formatı kabul edilebilir',
mov: 'Yalnızca mov formatı kabul edilebilir',
mkv: 'Yalnızca mkv formatı kabul edilebilir',
flv: 'Yalnızca flv biçimi kabul edilebilir'
}
},
it: {
@@ -428,6 +504,7 @@ module.exports = {
// convalide dello sviluppatore
Remember_me: "Remember_me parameter required",
// convalide della registrazione
name: "Inserisci nome",
first_name: "Inserisci nome",
last_name: "Inserisci il cognome",
email: "Enter email",
@@ -437,7 +514,6 @@ module.exports = {
username: "Inserisci nome utente",
phone_number: "Inserisci numero di telefono",
password: "Inserisci password",
password_confirmation: "Le password non sono le stesse",
// indirizzamento delle convalide
country: "Inserisci paese",
province: "Inserisci provincia",
@@ -455,8 +531,11 @@ module.exports = {
category: "Seleziona categoria",
image: "L'immagine è obbligatoria",
cover: "Cover is required",
file: "Il file è obbligatorio",
message: "Scrivi messaggio",
quantity: "Inserisci quantità"
quantity: "Inserisci quantità",
date: 'Enter date',
reason: 'Seleziona motivo'
},
format: {
phone_number: "Formato del numero di telefono non corretto",
@@ -526,7 +605,23 @@ module.exports = {
expired_reset_link: "L'attuale link del passaggio di reimpostazione è scaduto",
email_not_confirmed: "Conferma prima la tua email, il link di attivazione ti è già stato inviato.",
expired_activation_link: "Questo link di attivazione è scaduto",
success_activation: "Il tuo account è stato attivato con successo"
success_activation: "Il tuo account è stato attivato con successo",
passwords_not_match: "Le password non sono le stesse"
},
file_types: {
jpg: "È accettabile solo il formato jpg",
png: "È accettabile solo il formato png",
gif: "È accettabile solo il formato GIF",
pdf: "È accettabile solo il formato pdf",
txt: "È accettabile solo il formato txt",
log: "È accettabile solo il formato log",
mp3: "È accettabile solo il formato mp3",
ogg: "È accettabile solo il formato ogg",
wmv: "È accettabile solo il formato wmv",
mp4: "È accettabile solo il formato mp4",
mov: "È accettabile solo il formato mov",
mkv: "È accettabile solo il formato mkv",
flv: "È accettabile solo il formato flv"
}
}
}