handle all not found errors

This commit is contained in:
Amir Mohamadi
2021-12-31 17:01:17 +03:30
parent 5c07791225
commit 064d642b7e
47 changed files with 3386 additions and 3238 deletions
+113 -113
View File
@@ -8,136 +8,136 @@ const v_m = require('../validation_messages')
/////////////////////////////////////////////////////////////////////// register /////////////////////////////////////////////////////////////////////// register
module.exports.register = [ module.exports.register = [
[ [
body('name') body('name')
.isLength({min: 2}).withMessage(v_m['fa'].min_char.min2), .isLength({min: 2}).withMessage(v_m['fa'].min_char.min2),
body('username') body('username')
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4) .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
.custom((value, {req}) => { .custom((value, {req}) => {
return Admin.findOne({username: value}) return Admin.findOne({username: value})
.then(admin => { .then(admin => {
if (admin && admin.username === value) return Promise.reject(v_m['fa'].duplicated.username) if (admin && admin.username === value) return Promise.reject(v_m['fa'].duplicated.username)
else return true else return true
})
}),
body('password')
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
.custom((value, {req}) => {
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)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = {}
data.name = req.body.name
data.username = req.body.username
data.created_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(req.body.password, salt, (err, hash) => {
if (err) console.log(err)
data.password = hash
const admin = new Admin(data)
admin.save(err => {
if (err) console.log(err)
return res.json({message: v_m['fa'].response.success_save})
}) })
}) }),
})
} body('password')
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
.custom((value, {req}) => {
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)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = {}
data.name = req.body.name
data.username = req.body.username
data.created_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(req.body.password, salt, (err, hash) => {
if (err) console.log(err)
data.password = hash
const admin = new Admin(data)
admin.save(err => {
if (err) console.log(err)
return res.json({message: v_m['fa'].response.success_save})
})
})
})
}
] ]
/////////////////////////////////////////////////////////////////////// login /////////////////////////////////////////////////////////////////////// login
module.exports.login = [ module.exports.login = [
[ [
body('username') body('username')
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4) .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4)
.bail() .bail()
.if((value, {req}) => { .if((value, {req}) => {
return req.body.password && req.body.password.length >= 4 return req.body.password && req.body.password.length >= 4
}) })
.custom((value, {req}) => { .custom((value, {req}) => {
return Admin.findOne({username: value}) return Admin.findOne({username: value})
.then(admin => { .then(admin => {
if (!admin) return Promise.reject(v_m['fa'].not_found.admin_id) if (!admin) return Promise.reject(v_m['fa'].not_found.admin_id)
else return true else return true
})
}),
body('password')
.notEmpty().withMessage(v_m['fa'].required.password)
.bail()
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4),
body('remember_me')
.exists().withMessage(v_m['fa'].required.remember_me)
.bail()
.isBoolean().withMessage('مقدار باید از جنس Boolean باشد.')
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
Admin.findOne({username: req.body.username}, (err, user) => {
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: 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.save(err => {
if (err) console.log(err)
return res.json({token: token})
}) })
}) }),
body('password')
.notEmpty().withMessage(v_m['fa'].required.password)
.bail()
.isLength({min: 4}).withMessage(v_m['fa'].min_char.min4),
body('remember_me')
.exists().withMessage(v_m['fa'].required.remember_me)
.bail()
.isBoolean().withMessage('مقدار باید از جنس Boolean باشد.')
],
(req, res) => {
const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
Admin.findOne({username: req.body.username}, (err, user) => {
if (err) return res.status(404).json({message: 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: 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.save(err => {
if (err) console.log(err)
return res.json({token: token})
})
}) })
} })
}
] ]
/////////////////////////////////////////////////////////////////////// logout /////////////////////////////////////////////////////////////////////// logout
module.exports.logout = [ module.exports.logout = [
(req, res) => { (req, res) => {
const token = req.headers.authorization const token = req.headers.authorization
if (token) { if (token) {
Admin.findOneAndUpdate({token: token}, {token: null}, (err, oldData) => { Admin.findOneAndUpdate({token: token}, {token: null}, (err, oldData) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
if (oldData) return res.json({message: v_m['fa'].response.logged_out}) 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}) return res.status(401).json({message: v_m['fa'].response.not_logged_in})
}) })
} else { } else {
return res.status(401).json({message: v_m['fa'].response.not_logged_in}) return res.status(401).json({message: v_m['fa'].response.not_logged_in})
} }
} }
] ]
/////////////////////////////////////////////////////////////////////// get user /////////////////////////////////////////////////////////////////////// get user
module.exports.getUser = [ module.exports.getUser = [
config.isAdmin, config.isAdmin,
(req, res) => { (req, res) => {
const token = req.headers.authorization const token = req.headers.authorization
if (token) { if (token) {
jwt.verify(token, config.secretKey, (err, decoded) => { jwt.verify(token, config.secretKey, (err, decoded) => {
if (err) return res.status(401).json({message: 'unauthenticated'}) if (err) return res.status(401).json({message: 'unauthenticated'})
Admin.findById(decoded._id, (err, data) => { Admin.findById(decoded._id, (err, data) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
return res.json({user: data}) return res.json({user: data})
}) })
}) })
} else { } else {
return res.status(401).json({message: 'unauthenticated'}) return res.status(401).json({message: 'unauthenticated'})
} }
} }
] ]
/////////////////////////////////////////////////////////////////////// delete /////////////////////////////////////////////////////////////////////// delete
+4 -4
View File
@@ -105,7 +105,7 @@ module.exports.update = [
updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
} }
BlogCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => { BlogCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
return res.json({message: v_m['fa'].response.success_save}) return res.json({message: v_m['fa'].response.success_save})
}) })
} }
@@ -115,10 +115,10 @@ module.exports.update = [
module.exports.delete = [ module.exports.delete = [
(req, res) => { (req, res) => {
BlogPost.find({category: req.params.id}, (err, posts) => { BlogPost.find({category: req.params.id}, (err, posts) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
if (!posts.length) { if (!posts.length) {
BlogCategory.findByIdAndDelete(req.params.id, (err) => { BlogCategory.findByIdAndDelete(req.params.id, (err1) => {
if (err) return res.status(404).json({message: err}) if (err1) return res.status(404).json({message: err1})
return res.json({message: v_m['fa'].response.success_save}) return res.json({message: v_m['fa'].response.success_save})
}) })
} else { } else {
+15 -9
View File
@@ -80,6 +80,9 @@ module.exports.create = [
.cover(thumbWith, thumbHeight) .cover(thumbWith, thumbHeight)
.write(`./static/uploads/images/blog/thumb_${coverName}`) .write(`./static/uploads/images/blog/thumb_${coverName}`)
}) })
.catch(err => {
console.log(err)
})
const data = { const data = {
post_details: { post_details: {
@@ -112,7 +115,7 @@ module.exports.create = [
module.exports.getAll = [ module.exports.getAll = [
(req, res) => { (req, res) => {
BlogPost.find({}).sort({_id: -1}).exec((err, posts) => { BlogPost.find({}).sort({_id: -1}).exec((err, posts) => {
if (err) console.log(err) if (err) return res.status(500).json({message: err})
return res.json(posts) return res.json(posts)
}) })
} }
@@ -122,7 +125,7 @@ module.exports.getAll = [
module.exports.getOne = [ module.exports.getOne = [
(req, res) => { (req, res) => {
BlogPost.findById(req.params.id, (err, post) => { BlogPost.findById(req.params.id, (err, post) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
return res.json(post) return res.json(post)
}) })
} }
@@ -213,10 +216,13 @@ module.exports.update = [
.cover(thumbWith, thumbHeight) .cover(thumbWith, thumbHeight)
.write(`./static/uploads/images/blog/thumb_${coverName}`) .write(`./static/uploads/images/blog/thumb_${coverName}`)
}) })
.catch(err => {
console.log(err)
})
} }
BlogPost.findByIdAndUpdate(req.params.id, data, (err, oldData) => { BlogPost.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
if (cover && cover.data) { if (cover && cover.data) {
fs.unlink(`./static/${oldData.cover}`, err => { fs.unlink(`./static/${oldData.cover}`, err => {
if (err) console.log(err) if (err) console.log(err)
@@ -225,8 +231,8 @@ module.exports.update = [
if (err) console.log(err) if (err) console.log(err)
}) })
} }
BlogPost.findById(oldData._id, (err, newData) => { BlogPost.findById(oldData._id, (err1, newData) => {
if (err) console.log(err) if (err1) return res.status(404).json({message: err1})
return res.json(newData) return res.json(newData)
}) })
}) })
@@ -238,11 +244,11 @@ module.exports.delete = [
(req, res) => { (req, res) => {
BlogPost.findByIdAndDelete(req.params.id, (err, post) => { BlogPost.findByIdAndDelete(req.params.id, (err, post) => {
if (err) return res.status(404).json({message: err}) if (err) return res.status(404).json({message: err})
fs.unlink(`./static/${post.cover}`, err => { fs.unlink(`./static/${post.cover}`, err1 => {
if (err) console.log(err) if (err1) console.log(err1)
}) })
fs.unlink(`./static/${post.thumb}`, err => { fs.unlink(`./static/${post.thumb}`, err2 => {
if (err) console.log(err) if (err2) console.log(err2)
}) })
return res.json({message: v_m['fa'].response.success_remove}) return res.json({message: v_m['fa'].response.success_remove})
}) })
+91 -91
View File
@@ -4,110 +4,110 @@ const dateformat = require('dateformat')
const v_m = require('../validation_messages') const v_m = require('../validation_messages')
module.exports.create = [ module.exports.create = [
[ [
body('first_name') body('first_name')
.notEmpty() .notEmpty()
.withMessage((value, {req}) => { .withMessage((value, {req}) => {
return v_m[req.body.locale].required.first_name return v_m[req.body.locale].required.first_name
}) })
.bail() .bail()
.isLength({min: 2}) .isLength({min: 2})
.withMessage((value, {req}) => { .withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min2 return v_m[req.body.locale].min_char.min2
}), }),
body('last_name') body('last_name')
.notEmpty() .notEmpty()
.withMessage((value, {req}) => { .withMessage((value, {req}) => {
return v_m[req.body.locale].required.last_name return v_m[req.body.locale].required.last_name
}) })
.bail() .bail()
.isLength({min: 2}) .isLength({min: 2})
.withMessage((value, {req}) => { .withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min2 return v_m[req.body.locale].min_char.min2
}), }),
body('phone_number') body('phone_number')
.notEmpty() .notEmpty()
.withMessage((value, {req}) => { .withMessage((value, {req}) => {
return v_m[req.body.locale].required.phone_number return v_m[req.body.locale].required.phone_number
}) })
.bail() .bail()
.isNumeric() .isNumeric()
.withMessage((value, {req}) => { .withMessage((value, {req}) => {
return v_m[req.body.locale].format.phone_number return v_m[req.body.locale].format.phone_number
}), }),
body('email') body('email')
.notEmpty() .notEmpty()
.withMessage((value, {req}) => { .withMessage((value, {req}) => {
return v_m[req.body.locale].required.email return v_m[req.body.locale].required.email
}) })
.bail() .bail()
.isEmail() .isEmail()
.withMessage((value, {req}) => { .withMessage((value, {req}) => {
return v_m[req.body.locale].format.email return v_m[req.body.locale].format.email
}), }),
body('reason') body('reason')
.custom((value, {req}) => { .custom((value, {req}) => {
if (!value) return Promise.reject(v_m[req.body.locale].required.reason) if (!value) return Promise.reject(v_m[req.body.locale].required.reason)
else return true else return true
}), }),
body('message') body('message')
.isLength({min: 50}) .isLength({min: 50})
.withMessage((value, {req}) => { .withMessage((value, {req}) => {
return v_m[req.body.locale].min_char.min50 return v_m[req.body.locale].min_char.min50
}) })
], ],
(req, res) => { (req, res) => {
const errors = validationResult(req) const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = { const data = {
first_name: req.body.first_name, first_name: req.body.first_name,
last_name: req.body.last_name, last_name: req.body.last_name,
phone_number: req.body.phone_number, phone_number: req.body.phone_number,
email: req.body.email, email: req.body.email,
message: req.body.message, message: req.body.message,
reason: req.body.reason, reason: req.body.reason,
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
} }
const message = new ContactPageMessage(data) const message = new ContactPageMessage(data)
message.save((err, message) => { message.save((err, message) => {
if (err) console.log(err) if (err) console.log(err)
return res.json({message: v_m[req.body.locale].response.success_save}) return res.json({message: v_m[req.body.locale].response.success_save})
}) })
} }
] ]
module.exports.getAll = [ module.exports.getAll = [
(req, res) => { (req, res) => {
ContactPageMessage.find({}).select('-message') ContactPageMessage.find({}).select('-message')
.then(messages => { .then(messages => {
return res.json(messages) return res.json(messages)
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
return res.status(500).json(err) return res.status(500).json({message: err})
}) })
} }
] ]
module.exports.getOne = [ module.exports.getOne = [
(req, res) => { (req, res) => {
ContactPageMessage.findById(req.params.id) ContactPageMessage.findById(req.params.id)
.then(message => { .then(message => {
message.read = true message.read = true
message.save() message.save()
return res.json(message) return res.json(message)
}) })
.catch(err => { .catch(err => {
return res.status(404).json(err) return res.status(404).json({message: err})
}) })
} }
] ]
+40 -40
View File
@@ -5,54 +5,54 @@ const v_m = require('../validation_messages')
module.exports.create = [ module.exports.create = [
[ [
body('fa_reason') body('fa_reason')
.notEmpty().withMessage(v_m['fa'].required.title), .notEmpty().withMessage(v_m['fa'].required.title),
body('en_reason') body('en_reason')
.notEmpty().withMessage(v_m['fa'].required.title) .notEmpty().withMessage(v_m['fa'].required.title)
], ],
(req, res) => { (req, res) => {
const errors = validationResult(req) const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = { const data = {
reason_details: { reason_details: {
fa: { fa: {
reason: req.body.fa_reason reason: req.body.fa_reason
}, },
en: { en: {
reason: req.body.en_reason reason: req.body.en_reason
} }
}, },
created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
} }
const reason = new Reason(data) const reason = new Reason(data)
reason.save(err => { reason.save(err => {
if (err) console.log(err) if (err) console.log(err)
Reason.find({}, (err2, data) => { Reason.find({}, (err2, data) => {
if (err2) console.log(err2) if (err2) console.log(err2)
return res.json(data) return res.json(data)
})
}) })
} })
}
] ]
module.exports.getAll = [ module.exports.getAll = [
(req, res) => { (req, res) => {
Reason.find({}, (err, data) => { Reason.find({}, (err, data) => {
if (err) console.log(err) if (err) console.log(err)
return res.json(data) return res.json(data)
}) })
} }
] ]
module.exports.delete = [ module.exports.delete = [
(req, res) => { (req, res) => {
Reason.findByIdAndDelete(req.params.id, (err, reason) => { Reason.findByIdAndDelete(req.params.id, (err, reason) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
return res.json({message: v_m['fa'].response.success_remove}) return res.json({message: v_m['fa'].response.success_remove})
}) })
} }
] ]
+3 -3
View File
@@ -84,7 +84,7 @@ module.exports.getAll = [
module.exports.getOne = [ module.exports.getOne = [
(req, res) => { (req, res) => {
History.findById(req.params.id, (err, data) => { History.findById(req.params.id, (err, data) => {
if (err) return res.status(404).json(err) if (err) return res.status(404).json({message: err})
return res.json(data) return res.json(data)
}) })
} }
@@ -151,7 +151,7 @@ module.exports.update = [
}) })
} else { } else {
History.findByIdAndUpdate(req.params.id, data, (err, oldData) => { History.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
return res.json(v_m['fa'].response.success_save) return res.json(v_m['fa'].response.success_save)
}) })
} }
@@ -162,7 +162,7 @@ module.exports.update = [
module.exports.delete = [ module.exports.delete = [
(req, res) => { (req, res) => {
History.findByIdAndDelete(req.params.id, (err, data) => { History.findByIdAndDelete(req.params.id, (err, data) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
fs.unlink(`./static/${data.image}`, err => { fs.unlink(`./static/${data.image}`, err => {
if (err) console.log(err) if (err) console.log(err)
return res.json(v_m['fa'].response.success_remove) return res.json(v_m['fa'].response.success_remove)
+1 -4
View File
@@ -8,11 +8,10 @@ module.exports.create = [
if (!req.files || !req.files.pdf) return res.status(422).json({validation: {pdf: {msg: v_m['fa'].required.file}}}) 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}}}) 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) => { MainCatalog.find({}, (err, catalogs) => {
if (err) console.log(err)
if (catalogs.length) { if (catalogs.length) {
let firstFile = catalogs[0] let firstFile = catalogs[0]
if (firstFile.file[req.body.locale]) fs.unlink(`./static/${firstFile.file[req.body.locale]}`, err => { if (firstFile.file[req.body.locale]) fs.unlink(`./static/${firstFile.file[req.body.locale]}`, err => {
if (err) console.log(err) if (err) console.log(err)
}) })
@@ -24,8 +23,6 @@ module.exports.create = [
req.files.pdf.mv(`./static/uploads/pdf/${req.body.locale}_${req.files.pdf.name}`) req.files.pdf.mv(`./static/uploads/pdf/${req.body.locale}_${req.files.pdf.name}`)
return res.json(firstFile) return res.json(firstFile)
}) })
} else { } else {
const data = {created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss'), file: {}} const data = {created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss'), file: {}}
data.file[req.body.locale] = req.body.locale + '_' + req.files.pdf.name data.file[req.body.locale] = req.body.locale + '_' + req.files.pdf.name
+41 -2
View File
@@ -168,6 +168,9 @@ module.exports.createProduct = [
.quality(thumbQuality) .quality(thumbQuality)
.write(`./static/uploads/images/products/${thumb}`) .write(`./static/uploads/images/products/${thumb}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.more_section_image1) { if (req.files.more_section_image1) {
await jimp.read(req.files.more_section_image1.data) await jimp.read(req.files.more_section_image1.data)
@@ -178,6 +181,9 @@ module.exports.createProduct = [
.quality(moreSectionQuality) .quality(moreSectionQuality)
.write(`./static/uploads/images/products/${more_section_image1}`) .write(`./static/uploads/images/products/${more_section_image1}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.more_section_image2) { if (req.files.more_section_image2) {
await jimp.read(req.files.more_section_image2.data) await jimp.read(req.files.more_section_image2.data)
@@ -188,6 +194,9 @@ module.exports.createProduct = [
.quality(moreSectionQuality) .quality(moreSectionQuality)
.write(`./static/uploads/images/products/${more_section_image2}`) .write(`./static/uploads/images/products/${more_section_image2}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.render_image1) { if (req.files.render_image1) {
await jimp.read(req.files.render_image1.data) await jimp.read(req.files.render_image1.data)
@@ -198,6 +207,9 @@ module.exports.createProduct = [
.quality(renderImageQuality) .quality(renderImageQuality)
.write(`./static/uploads/images/products/${render_image1}`) .write(`./static/uploads/images/products/${render_image1}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.render_image2) { if (req.files.render_image2) {
await jimp.read(req.files.render_image2.data) await jimp.read(req.files.render_image2.data)
@@ -208,6 +220,9 @@ module.exports.createProduct = [
.quality(renderImageQuality) .quality(renderImageQuality)
.write(`./static/uploads/images/products/${render_image2}`) .write(`./static/uploads/images/products/${render_image2}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.chart_image) { if (req.files.chart_image) {
await jimp.read(req.files.chart_image.data) await jimp.read(req.files.chart_image.data)
@@ -216,6 +231,9 @@ module.exports.createProduct = [
.quality(chartImageQuality) .quality(chartImageQuality)
.write(`./static/uploads/images/products/${chart_image}`) .write(`./static/uploads/images/products/${chart_image}`)
}) })
.catch(err => {
console.log(err)
})
} }
} }
@@ -249,8 +267,8 @@ module.exports.getAllProducts = [
] ]
module.exports.getOneProduct = [ module.exports.getOneProduct = [
async (req, res) => { (req, res) => {
await Product.findById(req.params.id, async (err, product) => { Product.findById(req.params.id, (err, product) => {
if (err) return res.status(404).json({message: err}) if (err) return res.status(404).json({message: err})
return res.json(product) return res.json(product)
}) })
@@ -394,6 +412,9 @@ module.exports.updateProduct = [
.quality(thumbQuality) .quality(thumbQuality)
.write(`./static/uploads/images/products/${thumb}`) .write(`./static/uploads/images/products/${thumb}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.more_section_image1) { if (req.files.more_section_image1) {
@@ -406,6 +427,9 @@ module.exports.updateProduct = [
.quality(moreSectionQuality) .quality(moreSectionQuality)
.write(`./static/uploads/images/products/${more_section_image1}`) .write(`./static/uploads/images/products/${more_section_image1}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.more_section_image2) { if (req.files.more_section_image2) {
@@ -418,6 +442,9 @@ module.exports.updateProduct = [
.quality(moreSectionQuality) .quality(moreSectionQuality)
.write(`./static/uploads/images/products/${more_section_image2}`) .write(`./static/uploads/images/products/${more_section_image2}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.render_image1) { if (req.files.render_image1) {
@@ -430,6 +457,9 @@ module.exports.updateProduct = [
.quality(renderImageQuality) .quality(renderImageQuality)
.write(`./static/uploads/images/products/${render_image1}`) .write(`./static/uploads/images/products/${render_image1}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.render_image2) { if (req.files.render_image2) {
@@ -442,6 +472,9 @@ module.exports.updateProduct = [
.quality(renderImageQuality) .quality(renderImageQuality)
.write(`./static/uploads/images/products/${render_image2}`) .write(`./static/uploads/images/products/${render_image2}`)
}) })
.catch(err => {
console.log(err)
})
} }
if (req.files.chart_image) { if (req.files.chart_image) {
@@ -452,6 +485,9 @@ module.exports.updateProduct = [
.quality(chartImageQuality) .quality(chartImageQuality)
.write(`./static/uploads/images/products/${chart_image}`) .write(`./static/uploads/images/products/${chart_image}`)
}) })
.catch(err => {
console.log(err)
})
} }
} }
@@ -584,6 +620,9 @@ module.exports.createProductImage = [
return res.json(product) return res.json(product)
}) })
}) })
.catch(err => {
console.log(err)
})
} else { } else {
return res.status(422).json({validation: {images: {image: {msg: v_m['fa'].required.image}}}}) return res.status(422).json({validation: {images: {image: {msg: v_m['fa'].required.image}}}})
+160 -156
View File
@@ -7,196 +7,200 @@ const v_m = require('../validation_messages')
///////////////////////////////////////// create project ///////////////////////////////////////// create project
module.exports.create = [ module.exports.create = [
[ [
body('fa_name') body('fa_name')
.notEmpty().withMessage(v_m['fa'].required.title) .notEmpty().withMessage(v_m['fa'].required.title)
.bail() .bail()
.custom((value, {req}) => { .custom((value, {req}) => {
return Project.findOne({'project_details.fa.name': value}) return Project.findOne({'project_details.fa.name': value})
.then(project => { .then(project => {
if (project) return Promise.reject(v_m['fa'].duplicated.name) if (project) return Promise.reject(v_m['fa'].duplicated.name)
else return true else return true
}) })
}), }),
body('en_name') body('en_name')
.notEmpty().withMessage(v_m['fa'].required.title) .notEmpty().withMessage(v_m['fa'].required.title)
.bail() .bail()
.custom((value, {req}) => { .custom((value, {req}) => {
return Project.findOne({'project_details.en.name': value}) return Project.findOne({'project_details.en.name': value})
.then(project => { .then(project => {
if (project) return Promise.reject(v_m['fa'].duplicated.name) if (project) return Promise.reject(v_m['fa'].duplicated.name)
else return true else return true
}) })
}), }),
body('date') body('date')
.notEmpty().withMessage(v_m['fa'].required.date), .notEmpty().withMessage(v_m['fa'].required.date),
], ],
(req, res) => { (req, res) => {
const errors = validationResult(req) const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = { const data = {
date: req.body.date, date: req.body.date,
project_details: { project_details: {
fa: { fa: {
name: req.body.fa_name, name: req.body.fa_name,
description: req.body.fa_description, description: req.body.fa_description,
}, },
en: { en: {
name: req.body.en_name, name: req.body.en_name,
description: req.body.en_description, description: req.body.en_description,
} }
}, },
created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss') created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
} }
const project = new Project(data) const project = new Project(data)
project.save((err, project) => { project.save((err, project) => {
if (err) console.log(err) if (err) console.log(err)
return res.json(project) return res.json(project)
}) })
} }
] ]
///////////////////////////////////////// get all projects ///////////////////////////////////////// get all projects
module.exports.getAll = [ module.exports.getAll = [
(req, res) => { (req, res) => {
Project.find({}, (err, projects) => { Project.find({}, (err, projects) => {
if (err) return res.json({errors: err}) if (err) return res.json({errors: err})
return res.json(projects) return res.json(projects)
}) })
} }
] ]
///////////////////////////////////////// get one project ///////////////////////////////////////// get one project
module.exports.getOne = [ module.exports.getOne = [
(req, res) => { (req, res) => {
Project.findById(req.params.id, (err, project) => { Project.findById(req.params.id, (err, project) => {
if (err) return res.json({errors: err}) if (err) return res.status(404).json({errors: err})
return res.json(project) return res.json(project)
}) })
} }
] ]
///////////////////////////////////////// update one project ///////////////////////////////////////// update one project
module.exports.update = [ module.exports.update = [
[ [
body('fa_name') body('fa_name')
.notEmpty().withMessage(v_m['fa'].required.title) .notEmpty().withMessage(v_m['fa'].required.title)
.bail() .bail()
.custom((value, {req}) => { .custom((value, {req}) => {
return Project.findOne({'project_details.fa.name': value}) return Project.findOne({'project_details.fa.name': value})
.then(project => { .then(project => {
if (project && project._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name) if (project && project._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name)
else return true else return true
}) })
}), }),
body('en_name') body('en_name')
.notEmpty().withMessage(v_m['fa'].required.title) .notEmpty().withMessage(v_m['fa'].required.title)
.bail() .bail()
.custom((value, {req}) => { .custom((value, {req}) => {
return Project.findOne({'project_details.en.name': value}) return Project.findOne({'project_details.en.name': value})
.then(project => { .then(project => {
if (project && project._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name) if (project && project._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name)
else return true else return true
}) })
}), }),
body('date') body('date')
.notEmpty().withMessage(v_m['fa'].required.date), .notEmpty().withMessage(v_m['fa'].required.date),
], ],
(req, res) => { (req, res) => {
const errors = validationResult(req) const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = { const data = {
date: req.body.date, date: req.body.date,
project_details: { project_details: {
fa: { fa: {
name: req.body.fa_name, name: req.body.fa_name,
description: req.body.fa_description, description: req.body.fa_description,
}, },
en: { en: {
name: req.body.en_name, name: req.body.en_name,
description: req.body.en_description, description: req.body.en_description,
} }
}, },
updated_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss') updated_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
} }
Project.findByIdAndUpdate(req.params.id, data, (err, oldData) => { Project.findByIdAndUpdate(req.params.id, data, (err, oldData) => {
if (err) console.log(err) if (err) return res.status(404).json({message: err})
return res.json({message: v_m['fa'].response.success_save}) return res.json({message: v_m['fa'].response.success_save})
}) })
} }
] ]
///////////////////////////////////////// delete project ///////////////////////////////////////// delete project
module.exports.delete = [ module.exports.delete = [
(req, res) => { (req, res) => {
Project.findByIdAndRemove(req.params.id, (err, data) => { Project.findByIdAndRemove(req.params.id, (err, data) => {
if (err) return res.json({error: err}) if (err) return res.status(404).json({message: err})
data.images.forEach(async item => { data.images.forEach(async item => {
await fs.unlink(`./static/${item.image}`, err => { try {
if (err) console.log(err) await fs.unlink(`./static/${item.image}`, err => {
}) if (err) console.log(err)
}) })
return res.json({message: v_m['fa'].response.success_remove}) } catch (e) {
console.log(e)
}
}) })
} return res.json({message: v_m['fa'].response.success_remove})
})
}
] ]
//////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////// add images to project /////////////////////////////// add images to project
module.exports.addImage = [ module.exports.addImage = [
(req, res) => { (req, res) => {
Project.findById(req.params.id) Project.findById(req.params.id)
.then(project => { .then(project => {
if (!req.files || !req.files.image) return res.status(422).json({validation: {image: {msg: v_m['fa'].required.image}}}) 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] let fileName = 'project_' + Date.now() + '.' + req.files.image.mimetype.split('/')[1]
jimp.read(req.files.image.data) jimp.read(req.files.image.data)
.then(img => { .then(img => {
img img
.cover(1010, 534) .cover(1010, 534)
.quality(80) .quality(80)
.write(`./static/uploads/images/projects/${fileName}`) .write(`./static/uploads/images/projects/${fileName}`)
//// ////
const data = { const data = {
image: fileName, image: fileName,
created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss') created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
} }
project.images.push(data) project.images.push(data)
project.save(cb => { project.save(cb => {
return res.json(project) return res.json(project)
}) })
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
}) })
}) })
} }
] ]
module.exports.deleteImage = [ module.exports.deleteImage = [
(req, res) => { (req, res) => {
Project.findOne({'images._id': req.params.id}, (err, project) => { Project.findOne({'images._id': req.params.id}, (err, project) => {
if (err) console.log(err) if (err) console.log(err)
if (project) { if (project) {
let image = project.images.id(req.params.id) let image = project.images.id(req.params.id)
fs.unlink(`./static/${image.image}`, err => { fs.unlink(`./static/${image.image}`, err => {
if (err) console.log(err) if (err) console.log(err)
image.remove() image.remove()
project.save(cb => { project.save(cb => {
return res.json({message: v_m['fa'].response.success_remove}) return res.json({message: v_m['fa'].response.success_remove})
}) })
}) })
} }
}) })
} }
] ]
+135 -135
View File
@@ -7,167 +7,167 @@ const v_m = require('../validation_messages')
//////////////////////////////////////////////////////////////////////////////// create //////////////////////////////////////////////////////////////////////////////// create
module.exports.create = [ module.exports.create = [
[ [
body('fa_title') body('fa_title')
.isLength({max: 40}).withMessage(v_m['fa'].max_char.max40), .isLength({max: 40}).withMessage(v_m['fa'].max_char.max40),
body('en_title') body('en_title')
.isLength({max: 40}).withMessage(v_m['fa'].max_char.max40), .isLength({max: 40}).withMessage(v_m['fa'].max_char.max40),
body('fa_caption') body('fa_caption')
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100), .isLength({max: 100}).withMessage(v_m['fa'].max_char.max100),
body('en_caption') body('en_caption')
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100) .isLength({max: 100}).withMessage(v_m['fa'].max_char.max100)
], ],
(req, res) => { (req, res) => {
const errors = validationResult(req) const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
if (req.files) { if (req.files) {
let file = req.files.image let file = req.files.image
jimp.read(file.data) jimp.read(file.data)
.then(img => { .then(img => {
let fileName = 'image_' + Date.now() + '.' + img.getExtension() let fileName = 'image_' + Date.now() + '.' + img.getExtension()
if (img.bitmap.width >= 1920 && img.bitmap.height >= 1080) { if (img.bitmap.width >= 1920 && img.bitmap.height >= 1080) {
if (file.size / 1024 < 450) { if (file.size / 1024 < 450) {
file.mv(`./static/uploads/images/slider/${fileName}`, (err, img) => { file.mv(`./static/uploads/images/slider/${fileName}`, (err, img) => {
const slider = new Slider({ const slider = new Slider({
image: fileName, image: fileName,
slider_details: { slider_details: {
fa: { fa: {
title: req.body.fa_title, title: req.body.fa_title,
caption: req.body.fa_caption caption: req.body.fa_caption
}, },
en: { en: {
title: req.body.en_title, title: req.body.en_title,
caption: req.body.en_caption caption: req.body.en_caption
} }
}, },
created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss') created_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
}) })
slider.save((err, data) => { slider.save((err, data) => {
if (err) return res.status(500).json({error: err}) if (err) return res.status(500).json({error: err})
return res.json({message: v_m['fa'].response.success_save}) return res.json({message: v_m['fa'].response.success_save})
}) })
}) })
} else { } else {
return res.status(422).json({validation: {image: {msg: 'حجم تصویر نباید بیشتر از 450 کیلوبایت باشد'}}}) return res.status(422).json({validation: {image: {msg: 'حجم تصویر نباید بیشتر از 450 کیلوبایت باشد'}}})
} }
} else { } else {
return res.status(422).json({validation: {image: {msg: 'ابعاد تصویر حداقل 1920*1080 پیکسل قابل قبول میباشد.'}}}) return res.status(422).json({validation: {image: {msg: 'ابعاد تصویر حداقل 1920*1080 پیکسل قابل قبول میباشد.'}}})
} }
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
}) })
} else { } else {
return res.status(422).json({validation: {image: {msg: v_m['fa'].required.image}}}) return res.status(422).json({validation: {image: {msg: v_m['fa'].required.image}}})
} }
} }
] ]
//////////////////////////////////////////////////////////////////////////////// get all //////////////////////////////////////////////////////////////////////////////// get all
module.exports.getAll = [ module.exports.getAll = [
(req, res) => { (req, res) => {
Slider.find({}, (err, slides) => { Slider.find({}, (err, slides) => {
if (err) return res.status(404).json({error: err}) if (err) return res.status(404).json({error: err})
return res.json(slides) return res.json(slides)
}) })
} }
] ]
//////////////////////////////////////////////////////////////////////////////// get one //////////////////////////////////////////////////////////////////////////////// get one
module.exports.getOne = [ module.exports.getOne = [
(req, res) => { (req, res) => {
Slider.findById(req.params.id, (err, slide) => { Slider.findById(req.params.id, (err, slide) => {
if (err) return res.status(404).json({error: v_m['fa'].not_found.item_id}) if (err) return res.status(404).json({error: v_m['fa'].not_found.item_id})
return res.json(slide) return res.json(slide)
}) })
} }
] ]
//////////////////////////////////////////////////////////////////////////////// update //////////////////////////////////////////////////////////////////////////////// update
module.exports.update = [ module.exports.update = [
[ [
body('fa_title') body('fa_title')
.isLength({max: 40}).withMessage(v_m['fa'].max_char.max40), .isLength({max: 40}).withMessage(v_m['fa'].max_char.max40),
body('en_title') body('en_title')
.isLength({max: 40}).withMessage(v_m['fa'].max_char.max40), .isLength({max: 40}).withMessage(v_m['fa'].max_char.max40),
body('fa_caption') body('fa_caption')
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100), .isLength({max: 100}).withMessage(v_m['fa'].max_char.max100),
body('en_caption') body('en_caption')
.isLength({max: 100}).withMessage(v_m['fa'].max_char.max100) .isLength({max: 100}).withMessage(v_m['fa'].max_char.max100)
], ],
(req, res) => { (req, res) => {
const errors = validationResult(req) const errors = validationResult(req)
if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()})
const data = { const data = {
slider_details: { slider_details: {
fa: { fa: {
title: req.body.fa_title, title: req.body.fa_title,
caption: req.body.fa_caption caption: req.body.fa_caption
}, },
en: { en: {
title: req.body.en_title, title: req.body.en_title,
caption: req.body.en_caption caption: req.body.en_caption
} }
}, },
updated_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss') updated_at: dateFormat(Date.now(), 'yyyy-mm-dd HH:MM:ss')
} }
if (req.files) { if (req.files) {
let file = req.files.image let file = req.files.image
jimp.read(file.data) jimp.read(file.data)
.then(img => { .then(img => {
let fileName = 'image_' + Date.now() + '.' + img.getExtension() let fileName = 'image_' + Date.now() + '.' + img.getExtension()
data.image = fileName data.image = fileName
if (img.bitmap.width >= 1920 && img.bitmap.height >= 1080) { if (img.bitmap.width >= 1920 && img.bitmap.height >= 1080) {
if (file.size / 1024 < 450) { if (file.size / 1024 < 450) {
file.mv(`./static/uploads/images/slider/${fileName}`, (err) => { file.mv(`./static/uploads/images/slider/${fileName}`, (err) => {
if (err) console.log(err) if (err) console.log(err)
Slider.findByIdAndUpdate(req.params.id, data, (err, oldSlide) => { Slider.findByIdAndUpdate(req.params.id, data, (err, oldSlide) => {
if (err) return res.status(500).json({error: err}) if (err) return res.status(500).json({error: err})
fs.unlink(`./static/${oldSlide.image}`, err => { fs.unlink(`./static/${oldSlide.image}`, err => {
if (err) console.log(err) if (err) console.log(err)
}) })
return res.json({message: v_m['fa'].response.success_save}) return res.json({message: v_m['fa'].response.success_save})
}) })
}) })
} else { } else {
return res.status(422).json({validation: {image: {msg: 'حجم تصویر نباید بیشتر از 450 کیلوبایت باشد'}}}) return res.status(422).json({validation: {image: {msg: 'حجم تصویر نباید بیشتر از 450 کیلوبایت باشد'}}})
} }
} else { } else {
return res.status(422).json({validation: {image: {msg: 'ابعاد تصویر حداقل 1920*1080 پیکسل قابل قبول میباشد.'}}}) return res.status(422).json({validation: {image: {msg: 'ابعاد تصویر حداقل 1920*1080 پیکسل قابل قبول میباشد.'}}})
} }
})
.catch(err => {
console.log(err)
})
} else {
Slider.findByIdAndUpdate(req.params.id, data, (err, oldSlide) => {
if (err) return res.status(500).json({error: err})
return res.json({message: v_m['fa'].response.success_save})
}) })
} .catch(err => {
} console.log(err)
})
} else {
Slider.findByIdAndUpdate(req.params.id, data, (err, oldSlide) => {
if (err) return res.status(500).json({error: err})
return res.json({message: v_m['fa'].response.success_save})
})
}
}
] ]
//////////////////////////////////////////////////////////////////////////////// delete //////////////////////////////////////////////////////////////////////////////// delete
module.exports.delete = [ module.exports.delete = [
(req, res) => { (req, res) => {
Slider.findByIdAndRemove(req.params.id, (err, data) => { Slider.findByIdAndRemove(req.params.id, (err, data) => {
if (err) return res.json({error: err}) if (err) return res.json({error: err})
fs.unlink(`./static/${data.image}`, err => { fs.unlink(`./static/${data.image}`, err => {
if (err) console.log(err) if (err) console.log(err)
})
return res.json({message: v_m['fa'].response.success_remove})
}) })
} return res.json({message: v_m['fa'].response.success_remove})
})
}
] ]
+7 -3
View File
@@ -37,7 +37,7 @@
<nuxt-link :to="{name: 'lang',params: {lang: $route.params.lang}}" tag="li" exact class=""> <nuxt-link :to="{name: 'lang',params: {lang: $route.params.lang}}" tag="li" exact class="">
<a>{{ staticData.home }}</a> <a>{{ staticData.home }}</a>
</nuxt-link> </nuxt-link>
<nuxt-link :to="{name: 'lang-about',params: {lang: $route.params.lang}}" tag="li" exact class=""> <nuxt-link :to="{name: 'lang-about',params: {lang: $route.params.lang}}" tag="li" class="">
<a>{{ staticData.about }}</a> <a>{{ staticData.about }}</a>
</nuxt-link> </nuxt-link>
<nuxt-link :to="{name: 'lang-services',params: {lang: $route.params.lang}}" tag="li" exact class=""> <nuxt-link :to="{name: 'lang-services',params: {lang: $route.params.lang}}" tag="li" exact class="">
@@ -114,8 +114,12 @@ export default {
} }
}, },
async fetch() { async fetch() {
let catalog = await this.$axios.get('/api/public/catalog') try {
this.catalog = catalog.data let catalog = await this.$axios.get('/api/public/catalog')
this.catalog = catalog.data
} catch (e) {
this.$nuxt.context.error({status: 404, message: 'Catalog file not found'})
}
}, },
computed: { computed: {
staticData() { staticData() {
+9 -5
View File
@@ -44,7 +44,7 @@
</div> </div>
</section> </section>
<section class="s2" v-if="history.length"> <section class="s2" v-if="history.length" id="history_timeline">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
@@ -157,10 +157,14 @@ export default {
title: this.staticData.hero title: this.staticData.hero
} }
}, },
async asyncData({$axios}) { async asyncData({$axios, error}) {
const history = await $axios.get(`/api/public/history`) try {
return { const history = await $axios.get(`/api/public/history`)
history: history.data return {
history: history.data
}
} catch (e) {
error({status: 404, message: 'There is problem here'})
} }
} }
} }
+10 -6
View File
@@ -84,12 +84,16 @@ export default {
title: this.post.post_details[this.$route.params.lang].title title: this.post.post_details[this.$route.params.lang].title
} }
}, },
async asyncData({$axios, params}) { async asyncData({$axios, params, error}) {
const post = await $axios.get(`/api/public/blog/${params.post}`) try {
const blogCategories = await $axios.get(`/api/public/blogCategories`) const post = await $axios.get(`/api/public/blog/${params.post}`)
return { const blogCategories = await $axios.get(`/api/public/blogCategories`)
post: post.data, return {
blogCategories: blogCategories.data post: post.data,
blogCategories: blogCategories.data
}
} catch (e) {
error({status: 404, message: 'Page not found'})
} }
} }
} }
+10 -6
View File
@@ -119,12 +119,16 @@ export default {
title: this.staticData.hero title: this.staticData.hero
} }
}, },
async asyncData({$axios, store}) { async asyncData({$axios, store, error}) {
let posts = await $axios.get(`/api/public/blog`) try {
const blogCategories = await $axios.get(`/api/public/blogCategories`) let posts = await $axios.get(`/api/public/blog`)
return { const blogCategories = await $axios.get(`/api/public/blogCategories`)
posts: posts.data, return {
blogCategories: blogCategories.data posts: posts.data,
blogCategories: blogCategories.data
}
} catch (e) {
error({status: 404, message: 'There is a problem here'})
} }
} }
} }
+8 -4
View File
@@ -179,10 +179,14 @@ export default {
title: this.staticData.hero title: this.staticData.hero
} }
}, },
async asyncData({$axios}) { async asyncData({$axios, error}) {
const reasons = await $axios.get(`/api/public/contact/reason`) try {
return { const reasons = await $axios.get(`/api/public/contact/reason`)
reasons: reasons.data return {
reasons: reasons.data
}
} catch (e) {
error({status: 404, message: 'There is a problem here'})
} }
} }
} }
+13 -9
View File
@@ -42,7 +42,7 @@
<div class="col-12"> <div class="col-12">
<p>{{ staticData.s1_2.t2 }}</p> <p>{{ staticData.s1_2.t2 }}</p>
<p>{{ staticData.s1_2.t3 }}</p> <p>{{ staticData.s1_2.t3 }}</p>
<nuxt-link :to="{name: 'lang-about',params: {lang: $route.params.lang}}" class="btn btn-primary">{{ staticData.s1_2.link }}</nuxt-link> <nuxt-link :to="{name: 'lang-about',params: {lang: $route.params.lang},hash: '#history_timeline'}" class="btn btn-primary">{{ staticData.s1_2.link }}</nuxt-link>
</div> </div>
</div> </div>
</div> </div>
@@ -247,15 +247,19 @@ export default {
title: this.staticData.title title: this.staticData.title
} }
}, },
async asyncData({$axios}) { async asyncData({$axios, error}) {
const slider = await $axios.get('/api/public/slider') try {
const favoriteProducts = await $axios.get(`/api/public/favoriteProducts`) const slider = await $axios.get('/api/public/slider')
const catalog = await $axios.get('/api/public/catalog') const favoriteProducts = await $axios.get(`/api/public/favoriteProducts`)
const catalog = await $axios.get('/api/public/catalog')
return { return {
slider: slider.data, slider: slider.data,
favoriteProducts: favoriteProducts.data, favoriteProducts: favoriteProducts.data,
catalog: catalog.data catalog: catalog.data
}
} catch (e) {
error({status: 404, message: 'There is a problem here'})
} }
} }
} }
+10 -6
View File
@@ -177,12 +177,16 @@ export default {
title: this.product.product_details[this.$route.params.lang].name title: this.product.product_details[this.$route.params.lang].name
} }
}, },
async asyncData({$axios, params}) { async asyncData({$axios, params, error}) {
let product = await $axios.get(`/api/public/product/${params.product}`) try {
let productCategories = await $axios.get(`/api/public/productCategories`) let product = await $axios.get(`/api/public/product/${params.product}`)
return { let productCategories = await $axios.get(`/api/public/productCategories`)
product: product.data, return {
productCategories: productCategories.data product: product.data,
productCategories: productCategories.data
}
} catch (e) {
error({status: 404, message: 'Page not found'})
} }
} }
} }
+12 -8
View File
@@ -106,15 +106,19 @@ export default {
title: this.staticData.hero title: this.staticData.hero
} }
}, },
async asyncData({$axios, store}) { async asyncData({$axios, store, error}) {
const products = await $axios.get(`/api/public/products`) try {
const productCategories = await $axios.get(`/api/public/productCategories`) const products = await $axios.get(`/api/public/products`)
const catalog = await $axios.get('/api/public/catalog') const productCategories = await $axios.get(`/api/public/productCategories`)
const catalog = await $axios.get('/api/public/catalog')
return { return {
products: products.data, products: products.data,
productCategories: productCategories.data, productCategories: productCategories.data,
catalog: catalog.data catalog: catalog.data
}
} catch (e) {
error({status: 404, message: 'There is a problem here'})
} }
} }
} }
+8 -4
View File
@@ -107,10 +107,14 @@ export default {
title: this.staticData.hero title: this.staticData.hero
} }
}, },
async asyncData({$axios}) { async asyncData({$axios, error}) {
const projects = await $axios.get(`/api/public/projects`) try {
return { const projects = await $axios.get(`/api/public/projects`)
projects: projects.data return {
projects: projects.data
}
} catch (e) {
error({status: 404, message: 'There is a problem here'})
} }
} }
} }
+191 -191
View File
@@ -1,198 +1,198 @@
<template> <template>
<div class="page services--page"> <div class="page services--page">
<Hero :title="staticData.hero"/> <Hero :title="staticData.hero"/>
<section class="s1"> <section class="s1">
<div class="container"> <div class="container">
<div class="panel"> <div class="panel">
<div class="top"> <div class="top">
<h2 class="title">{{staticData.t1}}</h2> <h2 class="title">{{ staticData.t1 }}</h2>
<p class="subtitle">{{staticData.t2}}</p> <p class="subtitle">{{ staticData.t2 }}</p>
</div> </div>
<div class="content"> <div class="content">
<p>{{staticData.t3}}</p> <p>{{ staticData.t3 }}</p>
<h4>{{staticData.t4}}</h4> <h4>{{ staticData.t4 }}</h4>
<ul> <ul>
<li> <li>
<p>{{staticData.t5}}</p> <p>{{ staticData.t5 }}</p>
</li> </li>
<li> <li>
<p>{{staticData.t6}}</p> <p>{{ staticData.t6 }}</p>
</li> </li>
<li> <li>
<p>{{staticData.t7}}</p> <p>{{ staticData.t7 }}</p>
</li> </li>
<li> <li>
<p>{{staticData.t8}}</p> <p>{{ staticData.t8 }}</p>
</li> </li>
<li> <li>
<p>{{staticData.t9}}</p> <p>{{ staticData.t9 }}</p>
</li> </li>
<li> <li>
<p>{{staticData.t10}}</p> <p>{{ staticData.t10 }}</p>
</li> </li>
<li> <li>
<p>{{staticData.t11}}</p> <p>{{ staticData.t11 }}</p>
</li> </li>
</ul> </ul>
<div class="images"> <div class="images">
<img class="anim-fadeIn" src="~/assets/img/services/autodesk.png" alt=""> <img class="anim-fadeIn" src="~/assets/img/services/autodesk.png" alt="">
<img class="anim-fadeIn" src="~/assets/img/services/tekla.png" alt=""> <img class="anim-fadeIn" src="~/assets/img/services/tekla.png" alt="">
<img class="anim-fadeIn" src="~/assets/img/services/solid_works.png" alt=""> <img class="anim-fadeIn" src="~/assets/img/services/solid_works.png" alt="">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<section class="s2"> <section class="s2">
<img src="~/assets/img/services/services-s3-i1.jpg" alt="" class="section-bg anim-parallax"> <img src="~/assets/img/services/services-s3-i1.jpg" alt="" class="section-bg anim-parallax">
<div class="container"> <div class="container">
<div class="panel"> <div class="panel">
<div class="parts p1"> <div class="parts p1">
<h2 class="title title-shape-center">{{staticData.t12}}</h2> <h2 class="title title-shape-center">{{ staticData.t12 }}</h2>
<p>{{staticData.t13}}</p> <p>{{ staticData.t13 }}</p>
</div> </div>
<!-- image left --> <!-- image left -->
<div class="parts row align-items-center"> <div class="parts row align-items-center">
<div class="col-12 col-lg-6 order-1 order-lg-0"> <div class="col-12 col-lg-6 order-1 order-lg-0">
<h2 class="title title-subtitle">{{staticData.t14}}</h2> <h2 class="title title-subtitle">{{ staticData.t14 }}</h2>
<p>{{staticData.t15}}</p> <p>{{ staticData.t15 }}</p>
</div> </div>
<div class="col-12 col-lg-6 order-0 order-lg-1 mb-5 mb-lg-0"> <div class="col-12 col-lg-6 order-0 order-lg-1 mb-5 mb-lg-0">
<div class="imgBox imgBox-shape anim-fadeIn"> <div class="imgBox imgBox-shape anim-fadeIn">
<div class="img"> <div class="img">
<img src="~/assets/img/services/s2-i1.jpg" :alt="staticData.t14"> <img src="~/assets/img/services/s2-i1.jpg" :alt="staticData.t14">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- image right --> <!-- image right -->
<div class="parts row align-items-center"> <div class="parts row align-items-center">
<div class="col-12 col-lg-6 mb-5 mb-lg-0"> <div class="col-12 col-lg-6 mb-5 mb-lg-0">
<div class="imgBox imgBox-reverse imgBox-shape-reverse anim-fadeIn"> <div class="imgBox imgBox-reverse imgBox-shape-reverse anim-fadeIn">
<div class="img"> <div class="img">
<img src="~/assets/img/services/s2-i2.jpg" :alt="staticData.t16"> <img src="~/assets/img/services/s2-i2.jpg" :alt="staticData.t16">
</div> </div>
</div> </div>
</div> </div>
<div class="col-12 col-lg-6"> <div class="col-12 col-lg-6">
<h2 class="title title-subtitle">{{staticData.t16}}</h2> <h2 class="title title-subtitle">{{ staticData.t16 }}</h2>
<p>{{staticData.t17}}</p> <p>{{ staticData.t17 }}</p>
</div> </div>
</div> </div>
<!-- image left --> <!-- image left -->
<div class="parts row align-items-center"> <div class="parts row align-items-center">
<div class="col-12 col-lg-6 order-1 order-lg-0"> <div class="col-12 col-lg-6 order-1 order-lg-0">
<h2 class="title title-subtitle">{{staticData.t18}}</h2> <h2 class="title title-subtitle">{{ staticData.t18 }}</h2>
<p>{{staticData.t19}}</p> <p>{{ staticData.t19 }}</p>
</div> </div>
<div class="col-12 col-lg-6 order-0 order-lg-1 mb-5 mb-lg-0"> <div class="col-12 col-lg-6 order-0 order-lg-1 mb-5 mb-lg-0">
<div class="imgBox imgBox-shape anim-fadeIn"> <div class="imgBox imgBox-shape anim-fadeIn">
<div class="img"> <div class="img">
<img src="~/assets/img/services/s2-i3.jpg" :alt="staticData.t18"> <img src="~/assets/img/services/s2-i3.jpg" :alt="staticData.t18">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- image right --> <!-- image right -->
<div class="parts row align-items-center"> <div class="parts row align-items-center">
<div class="col-12 col-lg-6 mb-5 mb-lg-0"> <div class="col-12 col-lg-6 mb-5 mb-lg-0">
<div class="imgBox imgBox-reverse imgBox-shape-reverse anim-fadeIn"> <div class="imgBox imgBox-reverse imgBox-shape-reverse anim-fadeIn">
<div class="img"> <div class="img">
<img src="~/assets/img/services/s2-i4.jpg" :alt="staticData.t20"> <img src="~/assets/img/services/s2-i4.jpg" :alt="staticData.t20">
</div> </div>
</div> </div>
</div> </div>
<div class="col-12 col-lg-6"> <div class="col-12 col-lg-6">
<h2 class="title title-subtitle">{{staticData.t20}}</h2> <h2 class="title title-subtitle">{{ staticData.t20 }}</h2>
<p>{{staticData.t21}}</p> <p>{{ staticData.t21 }}</p>
</div> </div>
</div> </div>
<!-- image left --> <!-- image left -->
<div class="parts row align-items-center"> <div class="parts row align-items-center">
<div class="col-12 col-lg-6 order-1 order-lg-0"> <div class="col-12 col-lg-6 order-1 order-lg-0">
<h2 class="title title-subtitle">{{staticData.t22}}</h2> <h2 class="title title-subtitle">{{ staticData.t22 }}</h2>
<p>{{staticData.t23}}</p> <p>{{ staticData.t23 }}</p>
</div> </div>
<div class="col-12 col-lg-6 order-0 order-lg-1 mb-5 mb-lg-0"> <div class="col-12 col-lg-6 order-0 order-lg-1 mb-5 mb-lg-0">
<div class="imgBox imgBox-shape anim-fadeIn"> <div class="imgBox imgBox-shape anim-fadeIn">
<div class="img"> <div class="img">
<img src="~/assets/img/services/s2-i5.jpg" :alt="staticData.t22"> <img src="~/assets/img/services/s2-i5.jpg" :alt="staticData.t22">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- image right --> <!-- image right -->
<div class="parts row align-items-center"> <div class="parts row align-items-center">
<div class="col-12 col-lg-6 mb-5 mb-lg-0"> <div class="col-12 col-lg-6 mb-5 mb-lg-0">
<div class="imgBox imgBox-reverse imgBox-shape-reverse anim-fadeIn"> <div class="imgBox imgBox-reverse imgBox-shape-reverse anim-fadeIn">
<div class="img"> <div class="img">
<img src="~/assets/img/services/s2-i6.jpg" :alt="staticData.t24"> <img src="~/assets/img/services/s2-i6.jpg" :alt="staticData.t24">
</div> </div>
</div> </div>
</div> </div>
<div class="col-12 col-lg-6"> <div class="col-12 col-lg-6">
<h2 class="title title-subtitle">{{staticData.t24}}</h2> <h2 class="title title-subtitle">{{ staticData.t24 }}</h2>
<p>{{staticData.t25}}</p> <p>{{ staticData.t25 }}</p>
</div> </div>
</div> </div>
<!-- image left --> <!-- image left -->
<div class="parts row align-items-center"> <div class="parts row align-items-center">
<div class="col-12 col-lg-6 order-1 order-lg-0"> <div class="col-12 col-lg-6 order-1 order-lg-0">
<h2 class="title title-subtitle">{{staticData.t26}}</h2> <h2 class="title title-subtitle">{{ staticData.t26 }}</h2>
<p>{{staticData.t27}}</p> <p>{{ staticData.t27 }}</p>
</div> </div>
<div class="col-12 col-lg-6 order-0 order-lg-1 mb-5 mb-lg-0"> <div class="col-12 col-lg-6 order-0 order-lg-1 mb-5 mb-lg-0">
<div class="imgBox imgBox-shape anim-fadeIn"> <div class="imgBox imgBox-shape anim-fadeIn">
<div class="img"> <div class="img">
<img src="~/assets/img/services/s2-i7.jpg" :alt="staticData.t26"> <img src="~/assets/img/services/s2-i7.jpg" :alt="staticData.t26">
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<!-- image right --> <!-- image right -->
<div class="parts row align-items-center"> <div class="parts row align-items-center">
<div class="col-12 col-lg-6 mb-5 mb-lg-0"> <div class="col-12 col-lg-6 mb-5 mb-lg-0">
<div class="imgBox imgBox-reverse imgBox-shape-reverse anim-fadeIn"> <div class="imgBox imgBox-reverse imgBox-shape-reverse anim-fadeIn">
<div class="img"> <div class="img">
<img src="~/assets/img/services/s2-i8.jpg" :alt="staticData.t28"> <img src="~/assets/img/services/s2-i8.jpg" :alt="staticData.t28">
</div> </div>
</div> </div>
</div> </div>
<div class="col-12 col-lg-6"> <div class="col-12 col-lg-6">
<h2 class="title title-subtitle">{{staticData.t28}}</h2> <h2 class="title title-subtitle">{{ staticData.t28 }}</h2>
<p>{{staticData.t29}}</p> <p>{{ staticData.t29 }}</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
</div> </div>
</template> </template>
<script> <script>
import {fadeInAnimation, parallaxAnimation} from "~/mixins/animations" import {fadeInAnimation, parallaxAnimation} from "~/mixins/animations"
export default { export default {
computed: { computed: {
staticData() { staticData() {
return this.$store.state.staticData.services[this.$route.params.lang] return this.$store.state.staticData.services[this.$route.params.lang]
} }
}, },
mixins: [fadeInAnimation, parallaxAnimation], mixins: [fadeInAnimation, parallaxAnimation],
head() { head() {
return { return {
title: this.staticData.hero title: this.staticData.hero
} }
} }
} }
</script> </script>
+86 -86
View File
@@ -1,93 +1,93 @@
<template> <template>
<div class="page tech-info--page latin-digits"> <div class="page tech-info--page latin-digits">
<Hero :title="staticData.title"/> <Hero :title="staticData.title"/>
<section class="s1"> <section class="s1">
<div class="container"> <div class="container">
<div class="panel"> <div class="panel">
<div class="content gTech"> <div class="content gTech">
<h2 class="first">{{staticData.t1}}</h2> <h2 class="first">{{ staticData.t1 }}</h2>
<p>{{staticData.t2}}</p> <p>{{ staticData.t2 }}</p>
<br> <br>
<br> <br>
<br> <br>
<p> <p>
<b>{{staticData.t3}}</b> <b>{{ staticData.t3 }}</b>
<span>{{staticData.t4}}</span> <span>{{ staticData.t4 }}</span>
</p> </p>
<p> <p>
<b>{{staticData.t5}}</b> <b>{{ staticData.t5 }}</b>
<span>{{staticData.t6}}</span> <span>{{ staticData.t6 }}</span>
</p> </p>
<p> <p>
<b>{{staticData.t7}}</b> <b>{{ staticData.t7 }}</b>
<span>{{staticData.t8}}</span> <span>{{ staticData.t8 }}</span>
</p> </p>
<p> <p>
<b>{{staticData.t9}}</b> <b>{{ staticData.t9 }}</b>
<span>{{staticData.t10}}</span> <span>{{ staticData.t10 }}</span>
</p> </p>
<p> <p>
<b>{{staticData.t11}}</b> <b>{{ staticData.t11 }}</b>
<span>{{staticData.t12}}</span> <span>{{ staticData.t12 }}</span>
</p> </p>
<p> <p>
<b>{{staticData.t13}}</b> <b>{{ staticData.t13 }}</b>
<span>{{staticData.t14}}</span> <span>{{ staticData.t14 }}</span>
</p> </p>
<p> <p>
<b>{{staticData.t15}}</b> <b>{{ staticData.t15 }}</b>
<span>{{staticData.t16}}</span> <span>{{ staticData.t16 }}</span>
</p> </p>
<p> <p>
<b>{{staticData.t17}}</b> <b>{{ staticData.t17 }}</b>
<span>{{staticData.t18}}</span> <span>{{ staticData.t18 }}</span>
</p> </p>
<p> <p>
<b>{{staticData.t19}}</b> <b>{{ staticData.t19 }}</b>
<span>{{staticData.t20}}</span> <span>{{ staticData.t20 }}</span>
</p> </p>
<p> <p>
<b>{{staticData.t21}}</b> <b>{{ staticData.t21 }}</b>
<span>{{staticData.t22}}</span> <span>{{ staticData.t22 }}</span>
</p> </p>
<p>{{staticData.t23}}</p> <p>{{ staticData.t23 }}</p>
<div class="imgBox anim-fadeIn"> <div class="imgBox anim-fadeIn">
<img src="~/assets/img/tech-info/ti-Model-4.jpg" alt=""> <img src="~/assets/img/tech-info/ti-Model-4.jpg" alt="">
<p>{{staticData.t24}}</p> <p>{{ staticData.t24 }}</p>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<section class="s2"> <section class="s2">
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<h2 class="title">{{staticData.t25}}</h2> <h2 class="title">{{ staticData.t25 }}</h2>
<nuxt-link :to="{name: 'lang-products',params: {lang: $route.params.lang}}" class="btn btn-primary">{{staticData.t26}}</nuxt-link> <nuxt-link :to="{name: 'lang-products',params: {lang: $route.params.lang}}" class="btn btn-primary">{{ staticData.t26 }}</nuxt-link>
</div> </div>
</div> </div>
</div> </div>
</section> </section>
<CustomersCommunication/> <CustomersCommunication/>
</div> </div>
</template> </template>
<script> <script>
import {fadeInAnimation} from "~/mixins/animations" import {fadeInAnimation} from "~/mixins/animations"
export default { export default {
computed: { computed: {
staticData() { staticData() {
return this.$store.state.staticData.gTech[this.$route.params.lang] return this.$store.state.staticData.gTech[this.$route.params.lang]
} }
}, },
mixins: [fadeInAnimation], mixins: [fadeInAnimation],
head() { head() {
return { return {
title: this.staticData.title title: this.staticData.title
} }
} }
} }
</script> </script>
+10 -6
View File
@@ -180,12 +180,16 @@ export default {
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios, params}) { async asyncData({$axios, params, error}) {
const post = await $axios.get(`/api/public/blog/${params.post}`) try {
const blogCategories = await $axios.get(`/api/public/blogCategories`) const post = await $axios.get(`/api/public/blog/${params.post}`)
return { const blogCategories = await $axios.get(`/api/public/blogCategories`)
post: post.data, return {
blogCategories: blogCategories.data post: post.data,
blogCategories: blogCategories.data
}
} catch (e) {
error({status: 404, message: 'Page not found'})
} }
} }
} }
+99 -95
View File
@@ -1,102 +1,106 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">بروزرسانی</el-button> <el-button type="success" @click="upload">بروزرسانی</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی"> <el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی">
<el-input v-model="formData.blogCategory_details.fa.name"></el-input> <el-input v-model="formData.blogCategory_details.fa.name"></el-input>
<p class="err" v-if="validation.fa_name">{{validation.fa_name.msg}}</p> <p class="err" v-if="validation.fa_name">{{ validation.fa_name.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی"> <el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی">
<el-input v-model="formData.blogCategory_details.en.name"></el-input> <el-input v-model="formData.blogCategory_details.en.name"></el-input>
<p class="err" v-if="validation.en_name">{{validation.en_name.msg}}</p> <p class="err" v-if="validation.en_name">{{ validation.en_name.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: null, formData: null,
validation: {}, validation: {},
uploading: false, uploading: false,
uploadProgress: null uploadProgress: null
} }
}, },
computed: { computed: {
title() { title() {
if (!this.uploading) { if (!this.uploading) {
return 'اصلاح دسته بندی' return 'اصلاح دسته بندی'
} else { } else {
return this.uploadProgress return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = ''
const data = {
fa_name: this.formData.blogCategory_details.fa.name,
en_name: this.formData.blogCategory_details.en.name
}
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/blogCategories/${this.formData._id}`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'دسته بندی با موفقیت بروزرسانی شد.',
type: 'success'
})
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, params}) {
const category = await $axios.get(`/api/public/blogCategories/${params.category}`)
return {
formData: category.data
}
} }
} }
},
methods: {
upload() {
this.validation = ''
const data = {
fa_name: this.formData.blogCategory_details.fa.name,
en_name: this.formData.blogCategory_details.en.name
}
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/blogCategories/${this.formData._id}`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'دسته بندی با موفقیت بروزرسانی شد.',
type: 'success'
})
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, params, error}) {
try {
const category = await $axios.get(`/api/public/blogCategories/${params.category}`)
return {
formData: category.data
}
} catch (e) {
error({status: 404, message: 'Page not found'})
}
}
}
</script> </script>
+94 -90
View File
@@ -1,97 +1,101 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<nuxt-link :to="{name: 'admin-blog-category-new'}"> <nuxt-link :to="{name: 'admin-blog-category-new'}">
<el-button type="success">جدید</el-button> <el-button type="success">جدید</el-button>
</nuxt-link> </nuxt-link>
</admin-title-bar> </admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<el-table <el-table
:data="blogCategories" :data="blogCategories"
style="width: 100%"> style="width: 100%">
<el-table-column <el-table-column
type="index" type="index"
label="#"> label="#">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="blogCategory_details.fa.name" prop="blogCategory_details.fa.name"
label="نام دسته بندی" label="نام دسته بندی"
width=""> width="">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="ویرایش" label="ویرایش"
width="150" width="150"
align="left"> align="left">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button> <el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button>
<el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button> <el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
title: 'دسته بندی بلاگ', title: 'دسته بندی بلاگ',
blogCategories: null blogCategories: null
} }
}, },
head() { head() {
return { return {
title: this.title, title: this.title,
} }
}, },
methods: { methods: {
edit(id) { edit(id) {
this.$router.push(`/admin/blog/category/${id}`) this.$router.push(`/admin/blog/category/${id}`)
}, },
del(id) { del(id) {
this.$confirm('این آیتم حذف شود؟', 'هشدار', { this.$confirm('این آیتم حذف شود؟', 'هشدار', {
confirmButtonText: 'بله', confirmButtonText: 'بله',
cancelButtonText: 'لغو', cancelButtonText: 'لغو',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$axios.delete(`/api/private/blogCategories/${id}`) this.$axios.delete(`/api/private/blogCategories/${id}`)
.then(response => { .then(response => {
this.blogCategories = this.blogCategories.filter(item => { this.blogCategories = this.blogCategories.filter(item => {
return item._id !== id return item._id !== id
}) })
this.$message({ this.$message({
type: 'success', type: 'success',
message: 'آیتم حذف شد' message: 'آیتم حذف شد'
}); });
}) })
.catch(err => { .catch(err => {
this.$alert(err.response.data.message, 'خطا', { this.$alert(err.response.data.message, 'خطا', {
confirmButtonText: 'OK' confirmButtonText: 'OK'
}) })
}) })
}).catch(() => { }).catch(() => {
this.$message({ this.$message({
type: 'warning', type: 'warning',
message: 'عملیات لغو شد' message: 'عملیات لغو شد'
}); });
}); });
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios}) { async asyncData({$axios, error}) {
let blogCategories = await $axios.get(`/api/public/blogCategories`) try {
return { let blogCategories = await $axios.get(`/api/public/blogCategories`)
blogCategories: blogCategories.data return {
} blogCategories: blogCategories.data
} }
} } catch (e) {
error({status: 404, message: 'There is a problem here'})
}
}
}
</script> </script>
+97 -99
View File
@@ -1,107 +1,105 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">ایجاد</el-button> <el-button type="success" @click="upload">ایجاد</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی"> <el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی">
<el-input v-model="formData.blogCategory_details.fa.name"></el-input> <el-input v-model="formData.blogCategory_details.fa.name"></el-input>
<p class="err" v-if="validation.fa_name">{{validation.fa_name.msg}}</p> <p class="err" v-if="validation.fa_name">{{ validation.fa_name.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی"> <el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی">
<el-input v-model="formData.blogCategory_details.en.name"></el-input> <el-input v-model="formData.blogCategory_details.en.name"></el-input>
<p class="err" v-if="validation.en_name">{{validation.en_name.msg}}</p> <p class="err" v-if="validation.en_name">{{ validation.en_name.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: { formData: {
blogCategory_details: { blogCategory_details: {
fa: { fa: {
name: '' name: ''
}, },
en: { en: {
name: '' name: ''
} }
} }
},
validation: {},
uploading: false,
uploadProgress: null
}
}, },
computed: { validation: {},
title() { uploading: false,
if (!this.uploading) { uploadProgress: null
return 'افزودن دسته بندی' }
} else { },
return this.uploadProgress computed: {
title() {
if (!this.uploading) {
return 'افزودن دسته بندی'
} else {
return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = {}
const data = {
fa_name: this.formData.blogCategory_details.fa.name,
en_name: this.formData.blogCategory_details.en.name
}
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.post(`/api/private/blogCategories`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'دسته بندی با موفقیت ثبت شد.',
type: 'success'
});
this.$router.push({name: 'admin-blog-category'})
} }
} }).catch(error => {
}, if (error.response.status === 422) {
methods: { this.validation = error.response.data.validation
upload() { this.$message({
this.validation = {} type: 'error',
const data = { message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
fa_name: this.formData.blogCategory_details.fa.name, })
en_name: this.formData.blogCategory_details.en.name } else {
} this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه'
const axiosConfig = { })
onUploadProgress: progressEvent => { }
this.uploading = true })
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%' }
},
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) { head() {
this.uploading = false return {
} title: this.title
} }
} },
this.$axios.post(`/api/private/blogCategories`, data, axiosConfig) layout: 'admin'
.then(response => { }
if (response.data) {
this.$message({
message: 'دسته بندی با موفقیت ثبت شد.',
type: 'success'
});
this.$router.push({name: 'admin-blog-category'})
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
}
},
head() {
return {
title: this.title
}
},
layout: 'admin'
}
</script> </script>
+129 -125
View File
@@ -1,132 +1,136 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<nuxt-link :to="{name: 'admin-blog-new'}"> <nuxt-link :to="{name: 'admin-blog-new'}">
<el-button type="success">جدید</el-button> <el-button type="success">جدید</el-button>
</nuxt-link> </nuxt-link>
</admin-title-bar> </admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<el-table <el-table
:data="posts" :data="posts"
style="width: 100%"> style="width: 100%">
<el-table-column <el-table-column
type="index" type="index"
label="#"> label="#">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="thumb" prop="thumb"
label="تصویر" label="تصویر"
width="230"> width="230">
<template slot-scope="scope"> <template slot-scope="scope">
<el-image <el-image
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
:src="scope.row.thumb" :src="scope.row.thumb"
fit="fit"> fit="fit">
</el-image> </el-image>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="post_details.fa.title" prop="post_details.fa.title"
label="عنوان" label="عنوان"
width=""> width="">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="category" prop="category"
label="دسته بندی" label="دسته بندی"
width=""> width="">
<template slot-scope="scope"> <template slot-scope="scope">
{{categoryName(scope.row.category)}} {{ categoryName(scope.row.category) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="published" prop="published"
label="وضعیت انتشار" label="وضعیت انتشار"
width=""> width="">
<template slot-scope="scope"> <template slot-scope="scope">
<p v-if="scope.row.published" style="color: green;">منتشر شده</p> <p v-if="scope.row.published" style="color: green;">منتشر شده</p>
<p v-else style="color: red;">منتشر نشده</p> <p v-else style="color: red;">منتشر نشده</p>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="ویرایش" label="ویرایش"
width="150" width="150"
align="left"> align="left">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button> <el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button>
<el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button> <el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
title: 'لیست بلاگ', title: 'لیست بلاگ',
posts: null, posts: null,
blogCategories: null blogCategories: null
} }
}, },
head() { head() {
return { return {
title: this.title, title: this.title,
} }
}, },
methods: { methods: {
categoryName(categoryID) { categoryName(categoryID) {
return this.blogCategories.filter(item => { return this.blogCategories.filter(item => {
return item._id === categoryID return item._id === categoryID
})[0].blogCategory_details.fa.name })[0].blogCategory_details.fa.name
}, },
edit(id) { edit(id) {
this.$router.push(`/admin/blog/${id}`) this.$router.push(`/admin/blog/${id}`)
}, },
del(id) { del(id) {
this.$confirm('این پست حذف شود؟', 'هشدار', { this.$confirm('این پست حذف شود؟', 'هشدار', {
confirmButtonText: 'بله', confirmButtonText: 'بله',
cancelButtonText: 'لغو', cancelButtonText: 'لغو',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$axios.delete(`/api/private/blog/${id}`) this.$axios.delete(`/api/private/blog/${id}`)
.then(response => { .then(response => {
this.posts = this.posts.filter(item => { this.posts = this.posts.filter(item => {
return item._id !== id return item._id !== id
}) })
this.$message({ this.$message({
type: 'success', type: 'success',
message: 'آیتم حذف شد' message: 'آیتم حذف شد'
}) })
}) })
}).catch(() => { }).catch(() => {
this.$message({ this.$message({
type: 'warning', type: 'warning',
message: 'عملیات لغو شد' message: 'عملیات لغو شد'
}); });
}); });
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios, store}) { async asyncData({$axios, store, error}) {
let posts = await $axios.get(`/api/public/blog`) try {
const blogCategories = await $axios.get(`/api/public/blogCategories`) let posts = await $axios.get(`/api/public/blog`)
return { const blogCategories = await $axios.get(`/api/public/blogCategories`)
posts: posts.data, return {
blogCategories: blogCategories.data posts: posts.data,
} blogCategories: blogCategories.data
} }
} } catch (e) {
error({status: 404, message: 'There is a problem here'})
}
}
}
</script> </script>
+201 -197
View File
@@ -1,207 +1,211 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">ایجاد</el-button> <el-button type="success" @click="upload">ایجاد</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<h2>تصویر</h2> <h2>تصویر</h2>
<el-divider></el-divider> <el-divider></el-divider>
<img :src="post.cover" alt="" style="width: 100%"> <img :src="post.cover" alt="" style="width: 100%">
<input type="file" ref="cover" @change="preview"> <input type="file" ref="cover" @change="preview">
<p class="err" v-if="validation.cover">{{validation.cover.msg}}</p> <p class="err" v-if="validation.cover">{{ validation.cover.msg }}</p>
<el-form class="secondTitle"> <el-form class="secondTitle">
<el-form-item prop="category" :class="validation.category ? 'is-error' : ''" label="دسته بندی"> <el-form-item prop="category" :class="validation.category ? 'is-error' : ''" label="دسته بندی">
<el-select v-model="post.category" placeholder="انتخاب کنید"> <el-select v-model="post.category" placeholder="انتخاب کنید">
<el-option <el-option
v-for="item in blogCategories" v-for="item in blogCategories"
:key="item._id" :key="item._id"
:label="item.blogCategory_details.fa.name" :label="item.blogCategory_details.fa.name"
:value="item._id"> :value="item._id">
</el-option> </el-option>
</el-select> </el-select>
<p class="err" v-if="validation.category">{{validation.category.msg}}</p> <p class="err" v-if="validation.category">{{ validation.category.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="published" label="وضعیت انتشار پست"> <el-form-item prop="published" label="وضعیت انتشار پست">
<el-switch v-model="post.published" style="margin-right: 15px;"></el-switch> <el-switch v-model="post.published" style="margin-right: 15px;"></el-switch>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
<!-- fa --> <!-- fa -->
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<h2>فارسی</h2> <h2>فارسی</h2>
<el-divider></el-divider> <el-divider></el-divider>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان"> <el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان">
<el-input v-model="post.post_details.fa.title"></el-input> <el-input v-model="post.post_details.fa.title"></el-input>
<p class="err" v-if="validation.fa_title">{{validation.fa_title.msg}}</p> <p class="err" v-if="validation.fa_title">{{ validation.fa_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="short_description" :class="validation.fa_short_description ? 'is-error' : ''" label="توضیح کوتاه"> <el-form-item prop="short_description" :class="validation.fa_short_description ? 'is-error' : ''" label="توضیح کوتاه">
<el-input type="textarea" v-model="post.post_details.fa.short_description"></el-input> <el-input type="textarea" v-model="post.post_details.fa.short_description"></el-input>
<p class="err" v-if="validation.fa_short_description">{{validation.fa_short_description.msg}}</p> <p class="err" v-if="validation.fa_short_description">{{ validation.fa_short_description.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-divider></el-divider> <el-divider></el-divider>
<h6 style="margin-bottom: 30px;">توضیحات پست</h6> <h6 style="margin-bottom: 30px;">توضیحات پست</h6>
<client-only> <client-only>
<ckeditor v-model="post.post_details.fa.description" :config="editorConfig"></ckeditor> <ckeditor v-model="post.post_details.fa.description" :config="editorConfig"></ckeditor>
<p class="err" v-if="validation.fa_description">{{validation.fa_description.msg}}</p> <p class="err" v-if="validation.fa_description">{{ validation.fa_description.msg }}</p>
</client-only> </client-only>
</admin-panel> </admin-panel>
</div> </div>
<!-- en --> <!-- en -->
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<h2>انگلیسی</h2> <h2>انگلیسی</h2>
<el-divider></el-divider> <el-divider></el-divider>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان"> <el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان">
<el-input v-model="post.post_details.en.title"></el-input> <el-input v-model="post.post_details.en.title"></el-input>
<p class="err" v-if="validation.en_title">{{validation.en_title.msg}}</p> <p class="err" v-if="validation.en_title">{{ validation.en_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="short_description" :class="validation.en_short_description ? 'is-error' : ''" label="توضیح کوتاه"> <el-form-item prop="short_description" :class="validation.en_short_description ? 'is-error' : ''" label="توضیح کوتاه">
<el-input type="textarea" v-model="post.post_details.en.short_description"></el-input> <el-input type="textarea" v-model="post.post_details.en.short_description"></el-input>
<p class="err" v-if="validation.en_short_description">{{validation.en_short_description.msg}}</p> <p class="err" v-if="validation.en_short_description">{{ validation.en_short_description.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
<el-divider></el-divider> <el-divider></el-divider>
<h6 style="margin-bottom: 30px;">توضیحات پست</h6> <h6 style="margin-bottom: 30px;">توضیحات پست</h6>
<client-only> <client-only>
<ckeditor v-model="post.post_details.en.description" :config="editorConfig_en"></ckeditor> <ckeditor v-model="post.post_details.en.description" :config="editorConfig_en"></ckeditor>
<p class="err" v-if="validation.en_description">{{validation.en_description.msg}}</p> <p class="err" v-if="validation.en_description">{{ validation.en_description.msg }}</p>
</client-only> </client-only>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
post: { post: {
post_details: { post_details: {
fa: { fa: {
title: '', title: '',
description: '', description: '',
short_description: '' short_description: ''
}, },
en: { en: {
title: '', title: '',
description: '', description: '',
short_description: '' short_description: ''
} }
}, },
published: true, published: true,
category: '', category: '',
cover: '' cover: ''
},
blogCategories: null,
editorConfig: {
language: 'fa',
extraPlugins: ['bidi', 'justify']
},
editorConfig_en: {
language: 'en',
extraPlugins: ['bidi', 'justify']
},
validation: {},
uploading: false,
uploadProgress: null
}
}, },
computed: { blogCategories: null,
title() { editorConfig: {
if (!this.uploading) { language: 'fa',
return 'افزودن پست' extraPlugins: ['bidi', 'justify']
} else {
return this.uploadProgress
}
}
}, },
methods: { editorConfig_en: {
upload() { language: 'en',
this.validation = {} extraPlugins: ['bidi', 'justify']
const data = new FormData()
data.append('fa_title', this.post.post_details.fa.title)
data.append('en_title', this.post.post_details.en.title)
data.append('fa_description', this.post.post_details.fa.description)
data.append('en_description', this.post.post_details.en.description)
data.append('fa_short_description', this.post.post_details.fa.short_description)
data.append('en_short_description', this.post.post_details.en.short_description)
data.append('published', this.post.published)
data.append('category', this.post.category)
data.append('cover', this.$refs.cover.files[0])
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.post(`/api/private/blog`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'پست با موفقیت ثبت شد.',
type: 'success'
});
this.$router.push({name: 'admin-blog'})
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
},
preview(event) {
this.post.cover = URL.createObjectURL(event.target.files[0]);
}
}, },
head() { validation: {},
return { uploading: false,
title: this.title uploadProgress: null
} }
}, },
layout: 'admin', computed: {
async asyncData({$axios, store}) { title() {
const blogCategories = await $axios.get(`/api/public/blogCategories`) if (!this.uploading) {
return { return 'افزودن پست'
blogCategories: blogCategories.data } else {
} return this.uploadProgress
} }
} }
},
methods: {
upload() {
this.validation = {}
const data = new FormData()
data.append('fa_title', this.post.post_details.fa.title)
data.append('en_title', this.post.post_details.en.title)
data.append('fa_description', this.post.post_details.fa.description)
data.append('en_description', this.post.post_details.en.description)
data.append('fa_short_description', this.post.post_details.fa.short_description)
data.append('en_short_description', this.post.post_details.en.short_description)
data.append('published', this.post.published)
data.append('category', this.post.category)
data.append('cover', this.$refs.cover.files[0])
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.post(`/api/private/blog`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'پست با موفقیت ثبت شد.',
type: 'success'
});
this.$router.push({name: 'admin-blog'})
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
},
preview(event) {
this.post.cover = URL.createObjectURL(event.target.files[0])
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, store, error}) {
try {
const blogCategories = await $axios.get(`/api/public/blogCategories`)
return {
blogCategories: blogCategories.data
}
} catch (e) {
error({status: 404, message: 'There is a problem here'})
}
}
}
</script> </script>
+8 -4
View File
@@ -104,10 +104,14 @@ export default {
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios}) { async asyncData({$axios, error}) {
let catalog = await $axios.get('/api/public/catalog') try {
return { let catalog = await $axios.get('/api/public/catalog')
catalog: catalog.data return {
catalog: catalog.data
}
} catch (e) {
error({status: 404, message: 'There is a problem here'})
} }
} }
} }
+134 -130
View File
@@ -1,137 +1,141 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">بروز رسانی</el-button> <el-button type="success" @click="upload">بروز رسانی</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان فارسی"> <el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان فارسی">
<el-input v-model="formData.history_details.fa.title"></el-input> <el-input v-model="formData.history_details.fa.title"></el-input>
<p class="err" v-if="validation.fa_title">{{validation.fa_title.msg}}</p> <p class="err" v-if="validation.fa_title">{{ validation.fa_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان انگلیسی"> <el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان انگلیسی">
<el-input v-model="formData.history_details.en.title"></el-input> <el-input v-model="formData.history_details.en.title"></el-input>
<p class="err" v-if="validation.en_title">{{validation.en_title.msg}}</p> <p class="err" v-if="validation.en_title">{{ validation.en_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.fa_caption ? 'is-error' : ''" label="توضیحات فارسی"> <el-form-item prop="title" :class="validation.fa_caption ? 'is-error' : ''" label="توضیحات فارسی">
<el-input type="textarea" v-model="formData.history_details.fa.caption"></el-input> <el-input type="textarea" v-model="formData.history_details.fa.caption"></el-input>
<p class="err" v-if="validation.fa_caption">{{validation.fa_caption.msg}}</p> <p class="err" v-if="validation.fa_caption">{{ validation.fa_caption.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_caption ? 'is-error' : ''" label="توضیحات انگلیسی"> <el-form-item prop="title" :class="validation.en_caption ? 'is-error' : ''" label="توضیحات انگلیسی">
<el-input type="textarea" v-model="formData.history_details.en.caption"></el-input> <el-input type="textarea" v-model="formData.history_details.en.caption"></el-input>
<p class="err" v-if="validation.en_caption">{{validation.en_caption.msg}}</p> <p class="err" v-if="validation.en_caption">{{ validation.en_caption.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.year ? 'is-error' : ''" label="سال"> <el-form-item prop="title" :class="validation.year ? 'is-error' : ''" label="سال">
<el-input v-model="formData.year" placeholder="سال را چهار رقمی و به شمسی وارد کنید. مثال: 1399"></el-input> <el-input v-model="formData.year" placeholder="سال را چهار رقمی و به شمسی وارد کنید. مثال: 1399"></el-input>
<p class="err" v-if="validation.year">{{validation.year.msg}}</p> <p class="err" v-if="validation.year">{{ validation.year.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<h2 class="secondTitle">تصویر</h2> <h2 class="secondTitle">تصویر</h2>
<el-divider></el-divider> <el-divider></el-divider>
<img :src="formData.image" alt="" style="width: 100%;max-width: 400px;display: block;"> <img :src="formData.image" alt="" style="width: 100%;max-width: 400px;display: block;">
<input type="file" ref="image" @change="preview"> <input type="file" ref="image" @change="preview">
<p class="err" v-if="validation.image">{{validation.image.msg}}</p> <p class="err" v-if="validation.image">{{ validation.image.msg }}</p>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: null, formData: null,
validation: {}, validation: {},
uploading: false, uploading: false,
uploadProgress: null uploadProgress: null
} }
}, },
computed: { computed: {
title() { title() {
if (!this.uploading) { if (!this.uploading) {
return 'ویرایش تاریخچه' return 'ویرایش تاریخچه'
} else { } else {
return this.uploadProgress return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = ''
const data = new FormData()
data.append('fa_title', this.formData.history_details.fa.title)
data.append('en_title', this.formData.history_details.en.title)
data.append('fa_caption', this.formData.history_details.fa.caption)
data.append('en_caption', this.formData.history_details.en.caption)
data.append('year', this.formData.year)
if (this.$refs.image.files[0]) {
data.append('image', this.$refs.image.files[0])
}
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/history/${this.formData._id}`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'تغییرات با موفقیت انجام شد.',
type: 'success'
});
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.error.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
},
preview(event) {
this.formData.image = URL.createObjectURL(event.target.files[0]);
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, route}) {
const history = await $axios.get(`/api/public/history/${route.params.history}`)
return {
formData: history.data
}
} }
} }
},
methods: {
upload() {
this.validation = ''
const data = new FormData()
data.append('fa_title', this.formData.history_details.fa.title)
data.append('en_title', this.formData.history_details.en.title)
data.append('fa_caption', this.formData.history_details.fa.caption)
data.append('en_caption', this.formData.history_details.en.caption)
data.append('year', this.formData.year)
if (this.$refs.image.files[0]) {
data.append('image', this.$refs.image.files[0])
}
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/history/${this.formData._id}`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'تغییرات با موفقیت انجام شد.',
type: 'success'
});
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.error.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
},
preview(event) {
this.formData.image = URL.createObjectURL(event.target.files[0]);
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, route, error}) {
try {
const history = await $axios.get(`/api/public/history/${route.params.history}`)
return {
formData: history.data
}
} catch (e) {
error({status: 404, message: 'Page not found'})
}
}
}
</script> </script>
+111 -107
View File
@@ -1,119 +1,123 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<nuxt-link :to="{name: 'admin-history-new'}"> <nuxt-link :to="{name: 'admin-history-new'}">
<el-button type="success">جدید</el-button> <el-button type="success">جدید</el-button>
</nuxt-link> </nuxt-link>
</admin-title-bar> </admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<el-table <el-table
:data="history" :data="history"
style="width: 100%"> style="width: 100%">
<el-table-column <el-table-column
type="index" type="index"
label="#"> label="#">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="image" prop="image"
label="تصویر" label="تصویر"
width="230"> width="230">
<template slot-scope="scope"> <template slot-scope="scope">
<el-image <el-image
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
:src="scope.row.image" :src="scope.row.image"
fit="fit"> fit="fit">
</el-image> </el-image>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="year" prop="year"
label="سال" label="سال"
width=""> width="">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="history_details.fa.title" prop="history_details.fa.title"
label="عنوان" label="عنوان"
width=""> width="">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="ویرایش" label="ویرایش"
width="150" width="150"
align="left"> align="left">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button> <el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button>
<el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button> <el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
title: 'تاریخچه', title: 'تاریخچه',
history: null, history: null,
} }
}, },
head() { head() {
return { return {
title: this.title, title: this.title,
} }
}, },
methods: { methods: {
edit(id) { edit(id) {
this.$router.push(`/admin/history/${id}`) this.$router.push(`/admin/history/${id}`)
}, },
del(id) { del(id) {
this.$confirm('این مورد حذف شود؟', 'هشدار', { this.$confirm('این مورد حذف شود؟', 'هشدار', {
confirmButtonText: 'بله', confirmButtonText: 'بله',
cancelButtonText: 'لغو', cancelButtonText: 'لغو',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$axios.delete(`/api/private/history/${id}`).then(response => { this.$axios.delete(`/api/private/history/${id}`).then(response => {
this.history = this.history.filter(item => { this.history = this.history.filter(item => {
return item._id !== id return item._id !== id
}) })
this.$message({ this.$message({
type: 'success', type: 'success',
message: 'مورد حذف شد' message: 'مورد حذف شد'
}); });
}) })
}).catch(() => { }).catch(() => {
this.$message({ this.$message({
type: 'warning', type: 'warning',
message: 'عملیات لغو شد' message: 'عملیات لغو شد'
}); });
}); });
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios, store}) { async asyncData({$axios, store, error}) {
let history = await $axios.get(`/api/public/history`) try {
return { let history = await $axios.get(`/api/public/history`)
history: history.data return {
} history: history.data
} }
} } catch (e) {
error({status: 404, message: 'There is a problem here'})
}
}
}
</script> </script>
<style> <style>
.el-table .el-table__body-wrapper .el-table__row .is-left{ .el-table .el-table__body-wrapper .el-table__row .is-left{
text-align: left !important; text-align: left !important;
} }
</style> </style>
+127 -127
View File
@@ -1,137 +1,137 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">ایجاد</el-button> <el-button type="success" @click="upload">ایجاد</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان فارسی"> <el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان فارسی">
<el-input v-model="formData.fa_title"></el-input> <el-input v-model="formData.fa_title"></el-input>
<p class="err" v-if="validation.fa_title">{{validation.fa_title.msg}}</p> <p class="err" v-if="validation.fa_title">{{ validation.fa_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان انگلیسی"> <el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان انگلیسی">
<el-input v-model="formData.en_title"></el-input> <el-input v-model="formData.en_title"></el-input>
<p class="err" v-if="validation.en_title">{{validation.en_title.msg}}</p> <p class="err" v-if="validation.en_title">{{ validation.en_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.fa_caption ? 'is-error' : ''" label="توضیحات فارسی"> <el-form-item prop="title" :class="validation.fa_caption ? 'is-error' : ''" label="توضیحات فارسی">
<el-input type="textarea" v-model="formData.fa_caption"></el-input> <el-input type="textarea" v-model="formData.fa_caption"></el-input>
<p class="err" v-if="validation.fa_caption">{{validation.fa_caption.msg}}</p> <p class="err" v-if="validation.fa_caption">{{ validation.fa_caption.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_caption ? 'is-error' : ''" label="توضیحات انگلیسی"> <el-form-item prop="title" :class="validation.en_caption ? 'is-error' : ''" label="توضیحات انگلیسی">
<el-input type="textarea" v-model="formData.en_caption"></el-input> <el-input type="textarea" v-model="formData.en_caption"></el-input>
<p class="err" v-if="validation.en_caption">{{validation.en_caption.msg}}</p> <p class="err" v-if="validation.en_caption">{{ validation.en_caption.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.year ? 'is-error' : ''" label="سال"> <el-form-item prop="title" :class="validation.year ? 'is-error' : ''" label="سال">
<el-input v-model="formData.year" placeholder="سال را چهار رقمی و به شمسی وارد کنید. مثال: 1399"></el-input> <el-input v-model="formData.year" placeholder="سال را چهار رقمی و به شمسی وارد کنید. مثال: 1399"></el-input>
<p class="err" v-if="validation.year">{{validation.year.msg}}</p> <p class="err" v-if="validation.year">{{ validation.year.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<h2 class="secondTitle">تصویر</h2> <h2 class="secondTitle">تصویر</h2>
<el-divider></el-divider> <el-divider></el-divider>
<img :src="formData.image" alt="" style="width: 100%;max-width: 400px;display: block;"> <img :src="formData.image" alt="" style="width: 100%;max-width: 400px;display: block;">
<input type="file" ref="image" @change="preview"> <input type="file" ref="image" @change="preview">
<p class="err" v-if="validation.image">{{validation.image.msg}}</p> <p class="err" v-if="validation.image">{{ validation.image.msg }}</p>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: { formData: {
fa_title: '', fa_title: '',
en_title: '', en_title: '',
fa_caption: '', fa_caption: '',
en_caption: '', en_caption: '',
year: '', year: '',
image: '' image: ''
},
validation: {},
uploading: false,
uploadProgress: null
}
}, },
computed: { validation: {},
title() { uploading: false,
if (!this.uploading) { uploadProgress: null
return 'افزودن تاریخچه' }
} else { },
return this.uploadProgress computed: {
title() {
if (!this.uploading) {
return 'افزودن تاریخچه'
} else {
return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = ''
const data = new FormData()
data.append('fa_title', this.formData.fa_title)
data.append('en_title', this.formData.en_title)
data.append('fa_caption', this.formData.fa_caption)
data.append('en_caption', this.formData.en_caption)
data.append('year', this.formData.year)
data.append('image', this.$refs.image.files[0])
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.post(`/api/private/history`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'مورد با موفقیت ثبت شد.',
type: 'success'
});
this.$router.push({name: 'admin-history'})
} }
} }).catch(error => {
}, if (error.response.status === 422) {
methods: { this.validation = error.response.data.validation
upload() { this.$message({
this.validation = '' type: 'error',
const data = new FormData() message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
data.append('fa_title', this.formData.fa_title) })
data.append('en_title', this.formData.en_title) } else {
data.append('fa_caption', this.formData.fa_caption) this.$alert(error.response.data.error.message, 'خطا', {
data.append('en_caption', this.formData.en_caption) confirmButtonText: 'باشه',
data.append('year', this.formData.year)
data.append('image', this.$refs.image.files[0])
const axiosConfig = { })
onUploadProgress: progressEvent => { }
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) { })
this.uploading = false },
} preview(event) {
} this.formData.image = URL.createObjectURL(event.target.files[0])
} }
this.$axios.post(`/api/private/history`, data, axiosConfig) },
.then(response => { head() {
if (response.data) { return {
this.$message({ title: this.title
message: 'مورد با موفقیت ثبت شد.', }
type: 'success' },
}); layout: 'admin'
this.$router.push({name: 'admin-history'}) }
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.error.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
},
preview(event) {
this.formData.image = URL.createObjectURL(event.target.files[0]);
}
},
head() {
return {
title: this.title
}
},
layout: 'admin'
}
</script> </script>
+11 -13
View File
@@ -1,18 +1,16 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar title="صفحه اصلی پنل"/> <admin-title-bar title="صفحه اصلی پنل"/>
<div class="col-12"> <div class="col-12">
<h1>به پنل مدیریت خوش آمدید.</h1> <h1>به پنل مدیریت خوش آمدید.</h1>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
mounted() { layout: 'admin'
}, }
layout: 'admin'
}
</script> </script>
+1 -1
View File
@@ -61,6 +61,6 @@ export default {
.login { .login {
width: 100%; width: 100%;
max-width: 600px; max-width: 600px;
margin: 150px auto!important; margin: 150px auto !important;
} }
</style> </style>
+72 -68
View File
@@ -1,79 +1,83 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<el-form class="message"> <el-form class="message">
<el-form-item prop="title" label="دلیل ارتباط"> <el-form-item prop="title" label="دلیل ارتباط">
<el-input :value="message.reason" disabled></el-input> <el-input :value="message.reason" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="title" label="نام"> <el-form-item prop="title" label="نام">
<el-input :value="message.first_name" disabled></el-input> <el-input :value="message.first_name" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item prop="title" label="نام خانوادگی"> <el-form-item prop="title" label="نام خانوادگی">
<el-input :value="message.last_name" disabled></el-input> <el-input :value="message.last_name" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="شماره تماس"> <el-form-item label="شماره تماس">
<el-input :value="message.phone_number" disabled></el-input> <el-input :value="message.phone_number" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="ایمیل"> <el-form-item label="ایمیل">
<el-input :value="message.email" disabled></el-input> <el-input :value="message.email" disabled></el-input>
</el-form-item> </el-form-item>
<el-form-item label="پیام"> <el-form-item label="پیام">
<el-input type="textarea" disabled :value="message.message"></el-input> <el-input type="textarea" disabled :value="message.message"></el-input>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
title: 'خواندن پیام', title: 'خواندن پیام',
message: null, message: null,
user: null user: null
} }
}, },
mounted() { mounted() {
this.$axios.get('/api/private/contact') this.$axios.get('/api/private/contact')
.then(response => { .then(response => {
let unread = response.data.filter(item => { let unread = response.data.filter(item => {
return !item.read return !item.read
}) })
this.$store.commit('admin/unreadCount', unread.length) this.$store.commit('admin/unreadCount', unread.length)
}) })
}, },
head() { head() {
return { return {
title: this.title title: this.title
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios, params}) { async asyncData({$axios, params, error}) {
const message = await $axios.get(`/api/private/contact/${params.message}`) try {
return { const message = await $axios.get(`/api/private/contact/${params.message}`)
message: message.data return {
} message: message.data
} }
} } catch (e) {
error({status: 404, message: 'Page not found'})
}
}
}
</script> </script>
<style> <style>
.message input:disabled, .message textarea:disabled{ .message input:disabled, .message textarea:disabled{
color: #000 !important; color: #000 !important;
} }
</style> </style>
+179 -175
View File
@@ -1,187 +1,191 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"></admin-title-bar> <admin-title-bar :title="title"></admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<div class="row"> <div class="row">
<div class="col-6"> <div class="col-6">
<h2>افزودن دلایل تماس:</h2> <h2>افزودن دلایل تماس:</h2>
<el-divider></el-divider> <el-divider></el-divider>
<el-form> <el-form>
<el-form-item :class="validation.fa_reason ? 'is-error' : null" label="فارسی"> <el-form-item :class="validation.fa_reason ? 'is-error' : null" label="فارسی">
<el-input v-model="newReason.fa"></el-input> <el-input v-model="newReason.fa"></el-input>
<p class="err" v-if="validation.fa_reason">{{validation.fa_reason.msg}}</p> <p class="err" v-if="validation.fa_reason">{{ validation.fa_reason.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item :class="validation.en_reason ? 'is-error' : null" label="انگلیسی"> <el-form-item :class="validation.en_reason ? 'is-error' : null" label="انگلیسی">
<el-input v-model="newReason.en"></el-input> <el-input v-model="newReason.en"></el-input>
<p class="err" v-if="validation.en_reason">{{validation.en_reason.msg}}</p> <p class="err" v-if="validation.en_reason">{{ validation.en_reason.msg }}</p>
</el-form-item> </el-form-item>
<el-button @click="addReason" type="success">افزودن</el-button> <el-button @click="addReason" type="success">افزودن</el-button>
</el-form> </el-form>
</div> </div>
<div class="col-6"> <div class="col-6">
<el-tag <el-tag
v-for="item in reasons" v-for="item in reasons"
:key="item._id" :key="item._id"
closable closable
@close="removeReason(item._id)" @close="removeReason(item._id)"
type="primary" type="primary"
style="margin-left: 10px;"> style="margin-left: 10px;">
{{item.reason_details.fa.reason}} | {{item.reason_details.en.reason}} {{ item.reason_details.fa.reason }} | {{ item.reason_details.en.reason }}
</el-tag> </el-tag>
</div> </div>
</div> </div>
</admin-panel> </admin-panel>
</div> </div>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<el-table <el-table
:data="messages" :data="messages"
style="width: 100%" style="width: 100%"
:row-class-name="readStatus"> :row-class-name="readStatus">
<el-table-column <el-table-column
type="index" type="index"
label="#"> label="#">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="نام" label="نام"
width=""> width="">
<template slot-scope="scope"> <template slot-scope="scope">
{{fullName(scope.row.first_name,scope.row.last_name)}} {{ fullName(scope.row.first_name, scope.row.last_name) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="email" prop="email"
label="ایمیل" label="ایمیل"
width=""> width="">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="phone_number" prop="phone_number"
label="شماره تماس" label="شماره تماس"
width="" width=""
class-name="phoneNumber"> class-name="phoneNumber">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="reason" prop="reason"
label="دلیل تماس" label="دلیل تماس"
width="" width=""
class-name="phoneNumber"> class-name="phoneNumber">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="مشاهده" label="مشاهده"
width="80" width="80"
align="left"> align="left">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="success" plain icon="el-icon-view" @click="$router.push({name: 'admin-messages-message',params: {message: scope.row._id}})"></el-button> <el-button type="success" plain icon="el-icon-view" @click="$router.push({name: 'admin-messages-message',params: {message: scope.row._id}})"></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
title: 'لیست پیام های ارتباط با ما', title: 'لیست پیام های ارتباط با ما',
messages: null, messages: null,
reasons: null, reasons: null,
newReason: { newReason: {
fa: '', fa: '',
en: '' en: ''
},
validation: {}
}
}, },
head() { validation: {}
return { }
title: this.title, },
} head() {
}, return {
methods: { title: this.title,
readStatus({row, rowIndex}) { }
return row.read ? null : 'unread' },
}, methods: {
fullName(first, last) { readStatus({row, rowIndex}) {
return first + ' ' + last return row.read ? null : 'unread'
}, },
addReason() { fullName(first, last) {
this.validation = {} return first + ' ' + last
const data = { },
fa_reason: this.newReason.fa, addReason() {
en_reason: this.newReason.en, this.validation = {}
} const data = {
this.$axios.post(`/api/private/contact/reason`, data) fa_reason: this.newReason.fa,
.then(res => { en_reason: this.newReason.en,
this.reasons = res.data
this.newReason = {
fa: '',
en: ''
}
})
.catch(err => {
if (err.response.status === 422) this.validation = err.response.data.validation
else console.log(err.response.data.message)
})
},
removeReason(id) {
this.$confirm('این مورد حذف شود؟', 'هشدار', {
confirmButtonText: 'بله',
cancelButtonText: 'لغو',
type: 'warning'
}).then(() => {
this.$axios.delete(`/api/private/contact/reason/${id}`)
.then(res => {
this.$message({
message: 'با موفقیت حذف شد.',
type: 'error'
})
this.reasons = this.reasons.filter(item => {
return item._id !== id
})
})
.catch(err => {
console.log(err.response)
})
}).catch(() => {
this.$message({
type: 'warning',
message: 'عملیات لغو شد'
})
})
}
},
layout: 'admin',
async asyncData({$axios}) {
let messages = await $axios.get('/api/private/contact')
let reasons = await $axios.get('/api/public/contact/reason')
return {
messages: messages.data,
reasons: reasons.data
}
} }
} this.$axios.post(`/api/private/contact/reason`, data)
.then(res => {
this.reasons = res.data
this.newReason = {
fa: '',
en: ''
}
})
.catch(err => {
if (err.response.status === 422) this.validation = err.response.data.validation
else console.log(err.response.data.message)
})
},
removeReason(id) {
this.$confirm('این مورد حذف شود؟', 'هشدار', {
confirmButtonText: 'بله',
cancelButtonText: 'لغو',
type: 'warning'
}).then(() => {
this.$axios.delete(`/api/private/contact/reason/${id}`)
.then(res => {
this.$message({
message: 'با موفقیت حذف شد.',
type: 'error'
})
this.reasons = this.reasons.filter(item => {
return item._id !== id
})
})
.catch(err => {
console.log(err.response)
})
}).catch(() => {
this.$message({
type: 'warning',
message: 'عملیات لغو شد'
})
})
}
},
layout: 'admin',
async asyncData({$axios, error}) {
try {
let messages = await $axios.get('/api/private/contact')
let reasons = await $axios.get('/api/public/contact/reason')
return {
messages: messages.data,
reasons: reasons.data
}
} catch (e) {
error({status: 404, message: 'there is a problem here'})
}
}
}
</script> </script>
<style> <style>
.phoneNumber div{ .phoneNumber div{
direction: ltr; direction: ltr;
text-align: right text-align: right
} }
.unread{ .unread{
background: rgb(255, 173, 0, 0.12) !important; background: rgb(255, 173, 0, 0.12) !important;
} }
</style> </style>
+10 -6
View File
@@ -589,12 +589,16 @@ export default {
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios, params}) { async asyncData({$axios, params, error}) {
let product = await $axios.get(`/api/public/product/${params.product}`) try {
let productCategories = await $axios.get(`/api/public/productCategories`) let product = await $axios.get(`/api/public/product/${params.product}`)
return { let productCategories = await $axios.get(`/api/public/productCategories`)
formData: product.data, return {
productCategories: productCategories.data formData: product.data,
productCategories: productCategories.data
}
} catch (e) {
error({status: 404, message: 'Page not found'})
} }
} }
} }
+101 -97
View File
@@ -1,104 +1,108 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">بروزرسانی</el-button> <el-button type="success" @click="upload">بروزرسانی</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی"> <el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی">
<el-input v-model="formData.category_details.fa.name"></el-input> <el-input v-model="formData.category_details.fa.name"></el-input>
<p class="err" v-if="validation.fa_name">{{validation.fa_name.msg}}</p> <p class="err" v-if="validation.fa_name">{{ validation.fa_name.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی"> <el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی">
<el-input v-model="formData.category_details.en.name"></el-input> <el-input v-model="formData.category_details.en.name"></el-input>
<p class="err" v-if="validation.en_name">{{validation.en_name.msg}}</p> <p class="err" v-if="validation.en_name">{{ validation.en_name.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: null, formData: null,
validation: {}, validation: {},
uploading: false, uploading: false,
uploadProgress: null uploadProgress: null
} }
}, },
computed: { computed: {
title() { title() {
if (!this.uploading) { if (!this.uploading) {
return 'اصلاح دسته بندی' return 'اصلاح دسته بندی'
} else { } else {
return this.uploadProgress return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = {}
const data = new FormData()
data.append('fa_name', this.formData.category_details.fa.name)
data.append('en_name', this.formData.category_details.en.name)
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/productCategories/${this.formData._id}`, data, axiosConfig)
.then(response => {
this.$message({
message: 'دسته بندی با موفقیت بروزرسانی شد.',
type: 'success'
})
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, params}) {
const category = await $axios.get(`/api/public/productCategories/${params.category}`)
return {
formData: category.data
}
} }
} }
},
methods: {
upload() {
this.validation = {}
const data = new FormData()
data.append('fa_name', this.formData.category_details.fa.name)
data.append('en_name', this.formData.category_details.en.name)
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/productCategories/${this.formData._id}`, data, axiosConfig)
.then(response => {
this.$message({
message: 'دسته بندی با موفقیت بروزرسانی شد.',
type: 'success'
})
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, params, error}) {
try {
const category = await $axios.get(`/api/public/productCategories/${params.category}`)
return {
formData: category.data
}
} catch (e) {
error({status: 404, message: 'Page not found'})
}
}
}
</script> </script>
+95 -91
View File
@@ -1,98 +1,102 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<nuxt-link :to="{name: 'admin-products-category-new'}"> <nuxt-link :to="{name: 'admin-products-category-new'}">
<el-button type="success">جدید</el-button> <el-button type="success">جدید</el-button>
</nuxt-link> </nuxt-link>
</admin-title-bar> </admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<el-table <el-table
:data="categories" :data="categories"
style="width: 100%"> style="width: 100%">
<el-table-column <el-table-column
type="index" type="index"
label="#"> label="#">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="category_details.fa.name" prop="category_details.fa.name"
label="نام دسته بندی" label="نام دسته بندی"
width=""> width="">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="ویرایش" label="ویرایش"
width="150" width="150"
align="left"> align="left">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button> <el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button>
<el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button> <el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
title: 'دسته بندی محصولات', title: 'دسته بندی محصولات',
categories: null categories: null
} }
}, },
head() { head() {
return { return {
title: this.title, title: this.title,
} }
}, },
methods: { methods: {
edit(id) { edit(id) {
this.$router.push(`/admin/products/category/${id}`) this.$router.push(`/admin/products/category/${id}`)
}, },
del(id) { del(id) {
this.$confirm('این آیتم حذف شود؟', 'هشدار', { this.$confirm('این آیتم حذف شود؟', 'هشدار', {
confirmButtonText: 'بله', confirmButtonText: 'بله',
cancelButtonText: 'لغو', cancelButtonText: 'لغو',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$axios.delete(`/api/private/productCategories/${id}`) this.$axios.delete(`/api/private/productCategories/${id}`)
.then(response => { .then(response => {
this.categories = this.categories.filter(item => { this.categories = this.categories.filter(item => {
return item._id !== id return item._id !== id
}) })
this.$message({ this.$message({
type: 'success', type: 'success',
message: 'آیتم حذف شد' message: 'آیتم حذف شد'
}) })
}) })
.catch(err => { .catch(err => {
this.$message({ this.$message({
type: 'error', type: 'error',
message: err.response.data.message message: err.response.data.message
}) })
}) })
}).catch(() => { }).catch(() => {
this.$message({ this.$message({
type: 'warning', type: 'warning',
message: 'عملیات لغو شد' message: 'عملیات لغو شد'
}); });
}); });
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios}) { async asyncData({$axios, error}) {
let categories = await $axios.get(`/api/public/productCategories`); try {
return { let categories = await $axios.get(`/api/public/productCategories`);
categories: categories.data return {
} categories: categories.data
} }
} } catch (e) {
error({status: 404, message: 'There is a problem here'})
}
}
}
</script> </script>
+93 -94
View File
@@ -1,102 +1,101 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">ایجاد</el-button> <el-button type="success" @click="upload">ایجاد</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی"> <el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی">
<el-input v-model="formData.fa_name"></el-input> <el-input v-model="formData.fa_name"></el-input>
<p class="err" v-if="validation.fa_name">{{validation.fa_name.msg}}</p> <p class="err" v-if="validation.fa_name">{{ validation.fa_name.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی"> <el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی">
<el-input v-model="formData.en_name"></el-input> <el-input v-model="formData.en_name"></el-input>
<p class="err" v-if="validation.en_name">{{validation.en_name.msg}}</p> <p class="err" v-if="validation.en_name">{{ validation.en_name.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: { formData: {
fa_name: '', fa_name: '',
en_name: '' en_name: ''
},
validation: {},
uploading: false,
uploadProgress: null
}
}, },
computed: { validation: {},
title() { uploading: false,
if (!this.uploading) { uploadProgress: null
return 'افزودن دسته بندی' }
} else { },
return this.uploadProgress computed: {
title() {
if (!this.uploading) {
return 'افزودن دسته بندی'
} else {
return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = ''
const data = new FormData();
data.append('fa_name', this.formData.fa_name)
data.append('en_name', this.formData.en_name)
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.post(`/api/private/productCategories`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'دسته بندی با موفقیت ثبت شد.',
type: 'success'
});
this.$router.push({name: 'admin-products-category'})
} }
} }).catch(error => {
}, if (error.response.status === 422) {
methods: { this.validation = error.response.data.validation
upload() { this.$message({
this.validation = '' type: 'error',
const data = new FormData(); message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
data.append('fa_name', this.formData.fa_name) })
data.append('en_name', this.formData.en_name) } else {
this.$alert(error.response.data.message, 'خطا', {
const axiosConfig = { confirmButtonText: 'باشه'
onUploadProgress: progressEvent => { })
this.uploading = true }
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%' })
}
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) { },
this.uploading = false head() {
} return {
} title: this.title
} }
this.$axios.post(`/api/private/productCategories`, data, axiosConfig) },
.then(response => { layout: 'admin'
if (response.data) { }
this.$message({
message: 'دسته بندی با موفقیت ثبت شد.',
type: 'success'
});
this.$router.push({name: 'admin-products-category'})
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
}
},
head() {
return {
title: this.title
}
},
layout: 'admin'
}
</script> </script>
+10 -6
View File
@@ -130,12 +130,16 @@ export default {
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios, store}) { async asyncData({$axios, store, error}) {
let products = await $axios.get(`/api/public/products`) try {
let productCategories = await $axios.get(`/api/public/productCategories`) let products = await $axios.get(`/api/public/products`)
return { let productCategories = await $axios.get(`/api/public/productCategories`)
products: products.data, return {
productCategories: productCategories.data products: products.data,
productCategories: productCategories.data
}
} catch (e) {
error({status: 404, message: 'There is a problem here'})
} }
} }
} }
+8 -4
View File
@@ -435,10 +435,14 @@ export default {
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios, store}) { async asyncData({$axios, store, error}) {
let productCategories = await $axios.get(`/api/public/productCategories`) try {
return { let productCategories = await $axios.get(`/api/public/productCategories`)
productCategories: productCategories.data return {
productCategories: productCategories.data
}
} catch (e) {
error({status: 404, message: 'There is a problem here'})
} }
} }
} }
+230 -226
View File
@@ -1,237 +1,241 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">بروزرسانی</el-button> <el-button type="success" @click="upload">بروزرسانی</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی"> <el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی">
<el-input v-model="formData.project_details.fa.name"></el-input> <el-input v-model="formData.project_details.fa.name"></el-input>
<p class="err" v-if="validation.fa_name">{{validation.fa_name.msg}}</p> <p class="err" v-if="validation.fa_name">{{ validation.fa_name.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی"> <el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی">
<el-input v-model="formData.project_details.en.name"></el-input> <el-input v-model="formData.project_details.en.name"></el-input>
<p class="err" v-if="validation.en_name">{{validation.en_name.msg}}</p> <p class="err" v-if="validation.en_name">{{ validation.en_name.msg }}</p>
</el-form-item> </el-form-item>
<el-divider></el-divider> <el-divider></el-divider>
<el-form-item prop="title" :class="validation.fa_description ? 'is-error' : ''" label="توضیح فارسی"> <el-form-item prop="title" :class="validation.fa_description ? 'is-error' : ''" label="توضیح فارسی">
<el-input type="textarea" v-model="formData.project_details.fa.description"></el-input> <el-input type="textarea" v-model="formData.project_details.fa.description"></el-input>
<p class="err" v-if="validation.fa_description">{{validation.fa_description.msg}}</p> <p class="err" v-if="validation.fa_description">{{ validation.fa_description.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_description ? 'is-error' : ''" label="توضیح انگلیسی"> <el-form-item prop="title" :class="validation.en_description ? 'is-error' : ''" label="توضیح انگلیسی">
<el-input type="textarea" v-model="formData.project_details.en.description"></el-input> <el-input type="textarea" v-model="formData.project_details.en.description"></el-input>
<p class="err" v-if="validation.en_description">{{validation.en_description.msg}}</p> <p class="err" v-if="validation.en_description">{{ validation.en_description.msg }}</p>
</el-form-item> </el-form-item>
<el-divider></el-divider> <el-divider></el-divider>
<el-form-item prop="date" :class="validation.date ? 'is-error' : ''" label="تاریخ اجرا"> <el-form-item prop="date" :class="validation.date ? 'is-error' : ''" label="تاریخ اجرا">
<date-picker v-model="formData.date" format="YYYY-MM-DD" display-format="jYYYY/jMM/jDD"></date-picker> <date-picker v-model="formData.date" format="YYYY-MM-DD" display-format="jYYYY/jMM/jDD"></date-picker>
<p class="err" v-if="validation.date">{{validation.date.msg}}</p> <p class="err" v-if="validation.date">{{ validation.date.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<h2>تصاویر</h2> <h2>تصاویر</h2>
<el-divider></el-divider> <el-divider></el-divider>
<div class="newImg"> <div class="newImg">
<img :src="image" alt="" style="width: 100%;max-width: 300px;display: block"> <img :src="image" alt="" style="width: 100%;max-width: 300px;display: block">
<input type="file" ref="image" @change="previewGallery"> <input type="file" ref="image" @change="previewGallery">
<p class="err" v-if="validation.image">{{validation.image.msg}}</p> <p class="err" v-if="validation.image">{{ validation.image.msg }}</p>
<el-button type="primary" @click="addImage" style="margin-top: 10px;">افزودن</el-button> <el-button type="primary" @click="addImage" style="margin-top: 10px;">افزودن</el-button>
</div> </div>
<div class="images"> <div class="images">
<div class="imgBox" v-for="item in formData.images" :key="item._id"> <div class="imgBox" v-for="item in formData.images" :key="item._id">
<img :src="item.image" alt=""> <img :src="item.image" alt="">
<el-button type="danger" plain icon="el-icon-delete" class="dlt" v-if="item._id" @click="delImage(item._id)"></el-button> <el-button type="danger" plain icon="el-icon-delete" class="dlt" v-if="item._id" @click="delImage(item._id)"></el-button>
</div> </div>
</div> </div>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: null, formData: null,
image: '', image: '',
validation: {}, validation: {},
uploading: false, uploading: false,
uploadProgress: null uploadProgress: null
} }
}, },
computed: { computed: {
title() { title() {
if (!this.uploading) { if (!this.uploading) {
return 'ویرایش پروژه' return 'ویرایش پروژه'
} else { } else {
return this.uploadProgress return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = {}
const data = new FormData()
data.append('fa_name', this.formData.project_details.fa.name)
data.append('fa_description', this.formData.project_details.fa.description)
data.append('en_name', this.formData.project_details.en.name)
data.append('en_description', this.formData.project_details.en.description)
data.append('date', this.formData.date)
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/projects/${this.formData._id}`, data, axiosConfig)
.then(response => {
this.$message({
message: 'پروژه با موفقیت بروزرسانی شد.',
type: 'success'
})
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
},
addImage() {
this.validation = {}
const data = new FormData()
data.append('image', this.$refs.image.files[0])
this.$axios.post(`/api/private/projects/images/${this.formData._id}`, data)
.then(res => {
this.$message({
type: 'success',
message: 'تصویر جدید با موفقیت افزوده شد.'
})
this.$refs.image.value = null
this.image = ''
this.formData = res.data
})
.catch(err => {
if (err.response.status === 422) {
this.validation = err.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$message({
type: 'error',
message: err.response.data.message
})
}
})
},
delImage(id) {
this.$confirm('این آیتم حذف شود؟', 'هشدار', {
confirmButtonText: 'بله',
cancelButtonText: 'لغو',
type: 'warning'
}).then(() => {
this.$axios.delete(`/api/private/projects/images/${id}`)
.then(res => {
this.$message({
type: 'success',
message: 'تصویر با موفقیت حذف شد.'
})
this.formData.images = this.formData.images.filter(item => {
return item._id !== id
})
})
.catch(err => {
this.$message({
type: 'error',
message: err.response.data.message
})
})
}).catch(() => {
this.$message({
type: 'warning',
message: 'عملیات لغو شد'
})
})
},
previewGallery(event) {
this.image = URL.createObjectURL(event.target.files[0])
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, params}) {
let project = await $axios.get(`/api/public/projects/${params.project}`)
return {
formData: project.data
}
} }
} }
},
methods: {
upload() {
this.validation = {}
const data = new FormData()
data.append('fa_name', this.formData.project_details.fa.name)
data.append('fa_description', this.formData.project_details.fa.description)
data.append('en_name', this.formData.project_details.en.name)
data.append('en_description', this.formData.project_details.en.description)
data.append('date', this.formData.date)
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/projects/${this.formData._id}`, data, axiosConfig)
.then(response => {
this.$message({
message: 'پروژه با موفقیت بروزرسانی شد.',
type: 'success'
})
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
},
addImage() {
this.validation = {}
const data = new FormData()
data.append('image', this.$refs.image.files[0])
this.$axios.post(`/api/private/projects/images/${this.formData._id}`, data)
.then(res => {
this.$message({
type: 'success',
message: 'تصویر جدید با موفقیت افزوده شد.'
})
this.$refs.image.value = null
this.image = ''
this.formData = res.data
})
.catch(err => {
if (err.response.status === 422) {
this.validation = err.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$message({
type: 'error',
message: err.response.data.message
})
}
})
},
delImage(id) {
this.$confirm('این آیتم حذف شود؟', 'هشدار', {
confirmButtonText: 'بله',
cancelButtonText: 'لغو',
type: 'warning'
}).then(() => {
this.$axios.delete(`/api/private/projects/images/${id}`)
.then(res => {
this.$message({
type: 'success',
message: 'تصویر با موفقیت حذف شد.'
})
this.formData.images = this.formData.images.filter(item => {
return item._id !== id
})
})
.catch(err => {
this.$message({
type: 'error',
message: err.response.data.message
})
})
}).catch(() => {
this.$message({
type: 'warning',
message: 'عملیات لغو شد'
})
})
},
previewGallery(event) {
this.image = URL.createObjectURL(event.target.files[0])
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, params, error}) {
try {
let project = await $axios.get(`/api/public/projects/${params.project}`)
return {
formData: project.data
}
} catch (e) {
error({status: 404, message: 'Page not found'})
}
}
}
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.images { .images {
width: 100%; width: 100%;
margin-top: 30px; margin-top: 30px;
.imgBox { .imgBox {
border: 1px solid rgba(0, 0, 0, 0.05); border: 1px solid rgba(0, 0, 0, 0.05);
-webkit-border-radius: 5px; -webkit-border-radius: 5px;
-moz-border-radius: 5px; -moz-border-radius: 5px;
border-radius: 5px; border-radius: 5px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);
width: 200px; width: 200px;
position: relative; position: relative;
display: inline-block; display: inline-block;
margin: 5px; margin: 5px;
img { img {
width: 100%; width: 100%;
} }
.dlt { .dlt {
position: absolute; position: absolute;
bottom: 0; bottom: 0;
right: 0; right: 0;
} }
} }
} }
</style> </style>
+120 -116
View File
@@ -1,125 +1,129 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<nuxt-link :to="{name: 'admin-projects-new'}"> <nuxt-link :to="{name: 'admin-projects-new'}">
<el-button type="success">جدید</el-button> <el-button type="success">جدید</el-button>
</nuxt-link> </nuxt-link>
</admin-title-bar> </admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<el-table <el-table
:data="projects" :data="projects"
style="width: 100%"> style="width: 100%">
<el-table-column <el-table-column
type="index" type="index"
label="#"> label="#">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="تصویر" label="تصویر"
width="230"> width="230">
<template slot-scope="scope" v-if="scope.row.images[0]"> <template slot-scope="scope" v-if="scope.row.images[0]">
<el-image <el-image
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
:src="scope.row.images[0].image" :src="scope.row.images[0].image"
fit="fit"> fit="fit">
</el-image> </el-image>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="project_details.fa.name" prop="project_details.fa.name"
label="نام" label="نام"
width=""> width="">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="date" prop="date"
label="تاریخ اجرا" label="تاریخ اجرا"
width=""> width="">
<template slot-scope="scope"> <template slot-scope="scope">
{{jDate(scope.row.date)}} {{ jDate(scope.row.date) }}
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="ویرایش" label="ویرایش"
width="150" width="150"
align="left"> align="left">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button> <el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button>
<el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button> <el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import moment from "moment-jalaali" import moment from "moment-jalaali"
export default { export default {
data() { data() {
return { return {
title: 'لیست پروژه ها', title: 'لیست پروژه ها',
projects: null projects: null
} }
}, },
head() { head() {
return { return {
title: this.title, title: this.title,
} }
}, },
methods: { methods: {
jDate(date) { jDate(date) {
return moment(date).format('jYYYY/jMM/jDD') return moment(date).format('jYYYY/jMM/jDD')
}, },
edit(id) { edit(id) {
this.$router.push(`/admin/projects/${id}`) this.$router.push(`/admin/projects/${id}`)
}, },
del(id) { del(id) {
this.$confirm('این پروژه حذف شود؟', 'هشدار', { this.$confirm('این پروژه حذف شود؟', 'هشدار', {
confirmButtonText: 'بله', confirmButtonText: 'بله',
cancelButtonText: 'لغو', cancelButtonText: 'لغو',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$axios.delete(`/api/private/projects/${id}`) this.$axios.delete(`/api/private/projects/${id}`)
.then(response => { .then(response => {
this.projects = this.projects.filter(item => { this.projects = this.projects.filter(item => {
return item._id !== id return item._id !== id
}) })
this.$message({ this.$message({
type: 'success', type: 'success',
message: 'آیتم حذف شد' message: 'آیتم حذف شد'
}) })
}) })
.catch(err => { .catch(err => {
this.$message({ this.$message({
type: 'error', type: 'error',
message: err.response.data.message message: err.response.data.message
}) })
}) })
}).catch(() => { }).catch(() => {
this.$message({ this.$message({
type: 'warning', type: 'warning',
message: 'عملیات لغو شد' message: 'عملیات لغو شد'
}); });
}); });
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios, store}) { async asyncData({$axios, store, error}) {
let projects = await $axios.get(`/api/public/projects`) try {
return { let projects = await $axios.get(`/api/public/projects`)
projects: projects.data return {
} projects: projects.data
} }
} } catch (e) {
error({status: 404, message: 'There is a problem here'})
}
}
}
</script> </script>
+128 -129
View File
@@ -1,137 +1,136 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">ایجاد</el-button> <el-button type="success" @click="upload">ایجاد</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<el-form> <el-form>
<p style="margin-bottom: 50px;color: green;font-weight: bold;font-size: 20px;">ابتدا پروژه را ثبت کرده، سپس در مرحله بعد عکس ها را وارد کنید.</p> <p style="margin-bottom: 50px;color: green;font-weight: bold;font-size: 20px;">ابتدا پروژه را ثبت کرده، سپس در مرحله بعد عکس ها را وارد کنید.</p>
<el-divider></el-divider> <el-divider></el-divider>
<el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی"> <el-form-item prop="title" :class="validation.fa_name ? 'is-error' : ''" label="نام فارسی">
<el-input v-model="formData.project_details.fa.name"></el-input> <el-input v-model="formData.project_details.fa.name"></el-input>
<p class="err" v-if="validation.fa_name">{{validation.fa_name.msg}}</p> <p class="err" v-if="validation.fa_name">{{ validation.fa_name.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی"> <el-form-item prop="title" :class="validation.en_name ? 'is-error' : ''" label="نام انگلیسی">
<el-input v-model="formData.project_details.en.name"></el-input> <el-input v-model="formData.project_details.en.name"></el-input>
<p class="err" v-if="validation.en_name">{{validation.en_name.msg}}</p> <p class="err" v-if="validation.en_name">{{ validation.en_name.msg }}</p>
</el-form-item> </el-form-item>
<el-divider></el-divider> <el-divider></el-divider>
<el-form-item prop="title" :class="validation.fa_description ? 'is-error' : ''" label="توضیح فارسی"> <el-form-item prop="title" :class="validation.fa_description ? 'is-error' : ''" label="توضیح فارسی">
<el-input type="textarea" v-model="formData.project_details.fa.description"></el-input> <el-input type="textarea" v-model="formData.project_details.fa.description"></el-input>
<p class="err" v-if="validation.fa_description">{{validation.fa_description.msg}}</p> <p class="err" v-if="validation.fa_description">{{ validation.fa_description.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_description ? 'is-error' : ''" label="توضیح انگلیسی"> <el-form-item prop="title" :class="validation.en_description ? 'is-error' : ''" label="توضیح انگلیسی">
<el-input type="textarea" v-model="formData.project_details.en.description"></el-input> <el-input type="textarea" v-model="formData.project_details.en.description"></el-input>
<p class="err" v-if="validation.en_description">{{validation.en_description.msg}}</p> <p class="err" v-if="validation.en_description">{{ validation.en_description.msg }}</p>
</el-form-item> </el-form-item>
<el-divider></el-divider> <el-divider></el-divider>
<el-form-item prop="date" :class="validation.date ? 'is-error' : ''" label="تاریخ اجرا"> <el-form-item prop="date" :class="validation.date ? 'is-error' : ''" label="تاریخ اجرا">
<date-picker v-model="formData.date" format="YYYY-MM-DD" display-format="jYYYY/jMM/jDD"></date-picker> <date-picker v-model="formData.date" format="YYYY-MM-DD" display-format="jYYYY/jMM/jDD"></date-picker>
<p class="err" v-if="validation.date">{{validation.date.msg}}</p> <p class="err" v-if="validation.date">{{ validation.date.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: { formData: {
date: '', date: '',
project_details: { project_details: {
fa: { fa: {
name: '', name: '',
description: '' description: ''
}, },
en: { en: {
name: '', name: '',
description: '' description: ''
} }
} }
},
validation: {},
uploading: false,
uploadProgress: null
}
}, },
computed: { validation: {},
title() { uploading: false,
if (!this.uploading) { uploadProgress: null
return 'افزودن محصول' }
} else { },
return this.uploadProgress computed: {
title() {
if (!this.uploading) {
return 'افزودن محصول'
} else {
return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = {}
const data = new FormData()
data.append('fa_name', this.formData.project_details.fa.name)
data.append('fa_description', this.formData.project_details.fa.description)
data.append('en_name', this.formData.project_details.en.name)
data.append('en_description', this.formData.project_details.en.description)
data.append('date', this.formData.date)
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.post(`/api/private/projects`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'پروژه با موفقیت ثبت شد.',
type: 'success'
})
this.$router.push(`/admin/projects/${response.data._id}`)
} }
} }).catch(error => {
}, if (error.response.status === 422) {
methods: { this.validation = error.response.data.validation
upload() { this.$message({
this.validation = {} type: 'error',
const data = new FormData() message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
data.append('fa_name', this.formData.project_details.fa.name) })
data.append('fa_description', this.formData.project_details.fa.description) } else {
data.append('en_name', this.formData.project_details.en.name) this.$alert(error.response.data.message, 'خطا', {
data.append('en_description', this.formData.project_details.en.description) confirmButtonText: 'باشه'
data.append('date', this.formData.date) })
}
const axiosConfig = { })
onUploadProgress: progressEvent => { }
this.uploading = true },
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%' head() {
return {
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) { title: this.title
this.uploading = false }
} },
} layout: 'admin'
} }
this.$axios.post(`/api/private/projects`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'پروژه با موفقیت ثبت شد.',
type: 'success'
})
this.$router.push(`/admin/projects/${response.data._id}`)
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
}
},
head() {
return {
title: this.title
}
},
layout: 'admin'
}
</script> </script>
+126 -124
View File
@@ -1,131 +1,133 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">بروز رسانی</el-button> <el-button type="success" @click="upload">بروز رسانی</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان فارسی"> <el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان فارسی">
<el-input v-model="formData.slider_details.fa.title"></el-input> <el-input v-model="formData.slider_details.fa.title"></el-input>
<p class="err" v-if="validation.fa_title">{{validation.fa_title.msg}}</p> <p class="err" v-if="validation.fa_title">{{ validation.fa_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان انگلیسی"> <el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان انگلیسی">
<el-input v-model="formData.slider_details.en.title"></el-input> <el-input v-model="formData.slider_details.en.title"></el-input>
<p class="err" v-if="validation.en_title">{{validation.en_title.msg}}</p> <p class="err" v-if="validation.en_title">{{ validation.en_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.fa_caption ? 'is-error' : ''" label="توضیحات فارسی"> <el-form-item prop="title" :class="validation.fa_caption ? 'is-error' : ''" label="توضیحات فارسی">
<el-input v-model="formData.slider_details.fa.caption"></el-input> <el-input v-model="formData.slider_details.fa.caption"></el-input>
<p class="err" v-if="validation.fa_caption">{{validation.fa_caption.msg}}</p> <p class="err" v-if="validation.fa_caption">{{ validation.fa_caption.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_caption ? 'is-error' : ''" label="توضیحات انگلیسی"> <el-form-item prop="title" :class="validation.en_caption ? 'is-error' : ''" label="توضیحات انگلیسی">
<el-input v-model="formData.slider_details.en.caption"></el-input> <el-input v-model="formData.slider_details.en.caption"></el-input>
<p class="err" v-if="validation.en_caption">{{validation.en_caption.msg}}</p> <p class="err" v-if="validation.en_caption">{{ validation.en_caption.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<h2 class="secondTitle">تصویر</h2> <h2 class="secondTitle">تصویر</h2>
<el-divider></el-divider> <el-divider></el-divider>
<img :src="formData.image" alt="" style="width: 100%"> <img :src="formData.image" alt="" style="width: 100%">
<input type="file" ref="image" @change="preview"> <input type="file" ref="image" @change="preview">
<p class="err" v-if="validation.image">{{validation.image.msg}}</p> <p class="err" v-if="validation.image">{{ validation.image.msg }}</p>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: null, formData: null,
validation: {}, validation: {},
uploading: false, uploading: false,
uploadProgress: null uploadProgress: null
} }
}, },
computed: { computed: {
title() { title() {
if (!this.uploading) { if (!this.uploading) {
return 'ویرایش اسلاید' return 'ویرایش اسلاید'
} else { } else {
return this.uploadProgress return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = ''
const data = new FormData()
data.append('fa_title', this.formData.slider_details.fa.title)
data.append('en_title', this.formData.slider_details.en.title)
data.append('fa_caption', this.formData.slider_details.fa.caption)
data.append('en_caption', this.formData.slider_details.en.caption)
if (this.$refs.image.files[0]) {
data.append('image', this.$refs.image.files[0])
}
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/slider/${this.formData._id}`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'تغییرات با موفقیت انجام شد.',
type: 'success'
});
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.error.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
},
preview(event) {
this.formData.image = URL.createObjectURL(event.target.files[0]);
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, route}) {
const slide = await $axios.get(`/api/public/slider/${route.params.slide}`)
return {
formData: slide.data
}
} }
} }
},
methods: {
upload() {
this.validation = ''
const data = new FormData()
data.append('fa_title', this.formData.slider_details.fa.title)
data.append('en_title', this.formData.slider_details.en.title)
data.append('fa_caption', this.formData.slider_details.fa.caption)
data.append('en_caption', this.formData.slider_details.en.caption)
if (this.$refs.image.files[0]) {
data.append('image', this.$refs.image.files[0])
}
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.put(`/api/private/slider/${this.formData._id}`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'تغییرات با موفقیت انجام شد.',
type: 'success'
});
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.error.message, 'خطا', {
confirmButtonText: 'باشه'
})
}
})
},
preview(event) {
this.formData.image = URL.createObjectURL(event.target.files[0])
}
},
head() {
return {
title: this.title
}
},
layout: 'admin',
async asyncData({$axios, route, error}) {
try {
const slide = await $axios.get(`/api/public/slider/${route.params.slide}`)
return {
formData: slide.data
}
} catch (e) {
error({status: 404, message: 'Page not found'})
}
}
}
</script> </script>
+106 -102
View File
@@ -1,114 +1,118 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<nuxt-link :to="{name: 'admin-slider-new'}"> <nuxt-link :to="{name: 'admin-slider-new'}">
<el-button type="success">جدید</el-button> <el-button type="success">جدید</el-button>
</nuxt-link> </nuxt-link>
</admin-title-bar> </admin-title-bar>
<div class="col-12"> <div class="col-12">
<admin-panel> <admin-panel>
<el-table <el-table
v-if="slides" v-if="slides"
:data="slides" :data="slides"
style="width: 100%"> style="width: 100%">
<el-table-column <el-table-column
type="index" type="index"
label="#"> label="#">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="image" prop="image"
label="تصویر" label="تصویر"
width="230"> width="230">
<template slot-scope="scope"> <template slot-scope="scope">
<el-image <el-image
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
:src="scope.row.image" :src="scope.row.image"
fit="fit"> fit="fit">
</el-image> </el-image>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column <el-table-column
prop="slider_details.fa.title" prop="slider_details.fa.title"
label="عنوان" label="عنوان"
width=""> width="">
</el-table-column> </el-table-column>
<el-table-column <el-table-column
label="ویرایش" label="ویرایش"
width="150" width="150"
align="left"> align="left">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button> <el-button type="warning" plain icon="el-icon-edit" @click="edit(scope.row._id)"></el-button>
<el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button> <el-button type="danger" plain icon="el-icon-delete" @click="del(scope.row._id)"></el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
title: 'اسلایدر', title: 'اسلایدر',
slides: null, slides: null,
} }
}, },
head() { head() {
return { return {
title: this.title, title: this.title,
} }
}, },
methods: { methods: {
edit(id) { edit(id) {
this.$router.push(`/admin/slider/${id}`) this.$router.push(`/admin/slider/${id}`)
}, },
del(id) { del(id) {
this.$confirm('این تصویر حذف شود؟', 'هشدار', { this.$confirm('این تصویر حذف شود؟', 'هشدار', {
confirmButtonText: 'بله', confirmButtonText: 'بله',
cancelButtonText: 'لغو', cancelButtonText: 'لغو',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
this.$axios.delete(`/api/private/slider/${id}`).then(response => { this.$axios.delete(`/api/private/slider/${id}`).then(response => {
this.slides = this.slides.filter(item => { this.slides = this.slides.filter(item => {
return item._id !== id return item._id !== id
}) })
this.$message({ this.$message({
type: 'success', type: 'success',
message: 'تصویر حذف شد' message: 'تصویر حذف شد'
}); });
}) })
}).catch(() => { }).catch(() => {
this.$message({ this.$message({
type: 'warning', type: 'warning',
message: 'عملیات لغو شد' message: 'عملیات لغو شد'
}); });
}); });
} }
}, },
layout: 'admin', layout: 'admin',
async asyncData({$axios, store}) { async asyncData({$axios, store, error}) {
let slides = await $axios.get(`/api/public/slider`) try {
return { let slides = await $axios.get(`/api/public/slider`)
slides: slides.data return {
} slides: slides.data
} }
} } catch (e) {
error({status: 404, message: 'There is a problem here'})
}
}
}
</script> </script>
<style> <style>
.el-table .el-table__body-wrapper .el-table__row .is-left{ .el-table .el-table__body-wrapper .el-table__row .is-left{
text-align: left !important; text-align: left !important;
} }
</style> </style>
+119 -121
View File
@@ -1,129 +1,127 @@
<template> <template>
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<admin-title-bar :title="title"> <admin-title-bar :title="title">
<el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button> <el-button @click="$router.back()" type="primary">برگشت به صفحه قبل</el-button>
<el-button type="success" @click="upload">ایجاد</el-button> <el-button type="success" @click="upload">ایجاد</el-button>
</admin-title-bar> </admin-title-bar>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<el-form> <el-form>
<el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان فارسی"> <el-form-item prop="title" :class="validation.fa_title ? 'is-error' : ''" label="عنوان فارسی">
<el-input v-model="formData.fa_title"></el-input> <el-input v-model="formData.fa_title"></el-input>
<p class="err" v-if="validation.fa_title">{{validation.fa_title.msg}}</p> <p class="err" v-if="validation.fa_title">{{ validation.fa_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان انگلیسی"> <el-form-item prop="title" :class="validation.en_title ? 'is-error' : ''" label="عنوان انگلیسی">
<el-input v-model="formData.en_title"></el-input> <el-input v-model="formData.en_title"></el-input>
<p class="err" v-if="validation.en_title">{{validation.en_title.msg}}</p> <p class="err" v-if="validation.en_title">{{ validation.en_title.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.fa_caption ? 'is-error' : ''" label="توضیحات فارسی"> <el-form-item prop="title" :class="validation.fa_caption ? 'is-error' : ''" label="توضیحات فارسی">
<el-input v-model="formData.fa_caption"></el-input> <el-input v-model="formData.fa_caption"></el-input>
<p class="err" v-if="validation.fa_caption">{{validation.fa_caption.msg}}</p> <p class="err" v-if="validation.fa_caption">{{ validation.fa_caption.msg }}</p>
</el-form-item> </el-form-item>
<el-form-item prop="title" :class="validation.en_caption ? 'is-error' : ''" label="توضیحات انگلیسی"> <el-form-item prop="title" :class="validation.en_caption ? 'is-error' : ''" label="توضیحات انگلیسی">
<el-input v-model="formData.en_caption"></el-input> <el-input v-model="formData.en_caption"></el-input>
<p class="err" v-if="validation.en_caption">{{validation.en_caption.msg}}</p> <p class="err" v-if="validation.en_caption">{{ validation.en_caption.msg }}</p>
</el-form-item> </el-form-item>
</el-form> </el-form>
</admin-panel> </admin-panel>
</div> </div>
<div class="col-6"> <div class="col-6">
<admin-panel> <admin-panel>
<h2 class="secondTitle">تصویر</h2> <h2 class="secondTitle">تصویر</h2>
<el-divider></el-divider> <el-divider></el-divider>
<img :src="formData.image" alt="" style="width: 100%"> <img :src="formData.image" alt="" style="width: 100%">
<input type="file" ref="image" @change="preview"> <input type="file" ref="image" @change="preview">
<p class="err" v-if="validation.image">{{validation.image.msg}}</p> <p class="err" v-if="validation.image">{{ validation.image.msg }}</p>
</admin-panel> </admin-panel>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
data() { data() {
return { return {
formData: { formData: {
fa_title: '', fa_title: '',
en_title: '', en_title: '',
fa_caption: '', fa_caption: '',
en_caption: '', en_caption: '',
image: '' image: ''
},
validation: {},
uploading: false,
uploadProgress: null
}
}, },
computed: { validation: {},
title() { uploading: false,
if (!this.uploading) { uploadProgress: null
return 'افزودن اسلاید' }
} else { },
return this.uploadProgress computed: {
title() {
if (!this.uploading) {
return 'افزودن اسلاید'
} else {
return this.uploadProgress
}
}
},
methods: {
upload() {
this.validation = ''
const data = new FormData()
data.append('fa_title', this.formData.fa_title)
data.append('en_title', this.formData.en_title)
data.append('fa_caption', this.formData.fa_caption)
data.append('en_caption', this.formData.en_caption)
data.append('image', this.$refs.image.files[0])
const axiosConfig = {
onUploadProgress: progressEvent => {
this.uploading = true
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%'
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) {
this.uploading = false
}
}
}
this.$axios.post(`/api/private/slider`, data, axiosConfig)
.then(response => {
if (response.data) {
this.$message({
message: 'اسلاید با موفقیت ثبت شد.',
type: 'success'
});
this.$router.push({name: 'admin-slider'})
} }
} }).catch(error => {
}, if (error.response.status === 422) {
methods: { this.validation = error.response.data.validation
upload() { this.$message({
this.validation = '' type: 'error',
const data = new FormData() message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
data.append('fa_title', this.formData.fa_title) })
data.append('en_title', this.formData.en_title) } else {
data.append('fa_caption', this.formData.fa_caption) this.$alert(error.response.data.error.message, 'خطا', {
data.append('en_caption', this.formData.en_caption) confirmButtonText: 'باشه'
data.append('image', this.$refs.image.files[0]) })
}
const axiosConfig = { })
onUploadProgress: progressEvent => { },
this.uploading = true preview(event) {
this.uploadProgress = 'درحال آپلود ' + Math.floor(((progressEvent.loaded / progressEvent.total) * 100)) + '%' this.formData.image = URL.createObjectURL(event.target.files[0])
}
if ((progressEvent.loaded / progressEvent.total) * 100 === 100) { },
this.uploading = false head() {
} return {
} title: this.title
} }
this.$axios.post(`/api/private/slider`, data, axiosConfig) },
.then(response => { layout: 'admin'
if (response.data) { }
this.$message({
message: 'اسلاید با موفقیت ثبت شد.',
type: 'success'
});
this.$router.push({name: 'admin-slider'})
}
}).catch(error => {
if (error.response.status === 422) {
this.validation = error.response.data.validation
this.$message({
type: 'error',
message: 'اطلاعات رو بررسی و دوباره تلاش کنید'
})
} else {
this.$alert(error.response.data.error.message, 'خطا', {
confirmButtonText: 'باشه',
})
}
})
},
preview(event) {
this.formData.image = URL.createObjectURL(event.target.files[0]);
}
},
head() {
return {
title: this.title
}
},
layout: 'admin'
}
</script> </script>