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