diff --git a/api/controllers/blogCategoryController.js b/api/controllers/blogCategoryController.js index e05bedb..b2ab71d 100644 --- a/api/controllers/blogCategoryController.js +++ b/api/controllers/blogCategoryController.js @@ -5,125 +5,125 @@ const {body, validationResult} = require('express-validator') const v_m = require('../validation_messages') module.exports.create = [ - [ - body('fa_name') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .custom((value, {req}) => { - return BlogCategory.findOne({'blogCategory_details.fa.name': value}).then(category => { - if (category) return Promise.reject(v_m['fa'].duplicated.title) - return true - }) - }), - body('en_name') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .custom((value, {req}) => { - return BlogCategory.findOne({'blogCategory_details.en.name': value}).then(category => { - if (category) return Promise.reject(v_m['fa'].duplicated.title) - return true - }) + [ + body('fa_name') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .custom((value, {req}) => { + return BlogCategory.findOne({'blogCategory_details.fa.name': value}).then(category => { + if (category) return Promise.reject(v_m['fa'].duplicated.title) + return true }) - ], - (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + }), + body('en_name') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .custom((value, {req}) => { + return BlogCategory.findOne({'blogCategory_details.en.name': value}).then(category => { + if (category) return Promise.reject(v_m['fa'].duplicated.title) + return true + }) + }) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - const blogCategory = new BlogCategory({ - blogCategory_details: { - fa: { - name: req.body.fa_name - }, - en: { - name: req.body.en_name - } - }, - created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') - }) - blogCategory.save(err => { - if (err) console.log(err) - return res.json({message: v_m['fa'].response.success_save}) - }) - } + const blogCategory = new BlogCategory({ + blogCategory_details: { + fa: { + name: req.body.fa_name + }, + en: { + name: req.body.en_name + } + }, + created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + }) + blogCategory.save(err => { + if (err) console.log(err) + return res.json({message: v_m['fa'].response.success_save}) + }) + } ] module.exports.getAll = [ - (req, res) => { - BlogCategory.find({}, (err, categories) => { - if (err) return res.status(500).json({message: err}) - return res.json(categories) - }) - } + (req, res) => { + BlogCategory.find({}, (err, categories) => { + if (err) return res.status(500).json({message: err}) + return res.json(categories) + }) + } ] module.exports.getOne = [ - (req, res) => { - BlogCategory.findById(req.params.id, (err, category) => { - if (err) return res.status(404).json({message: err}) - return res.json(category) - }) - } + (req, res) => { + BlogCategory.findById(req.params.id, (err, category) => { + if (err) return res.status(404).json({message: err}) + return res.json(category) + }) + } ] module.exports.update = [ - [ - body('fa_name') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .custom((value, {req}) => { - return BlogCategory.findOne({'blogCategory_details.fa.name': value}).then(category => { - if (category && category._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title) - return true - }) - }), - body('en_name') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .custom((value, {req}) => { - return BlogCategory.findOne({'blogCategory_details.en.name': value}).then(category => { - if (category && category._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title) - return true - }) + [ + body('fa_name') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .custom((value, {req}) => { + return BlogCategory.findOne({'blogCategory_details.fa.name': value}).then(category => { + if (category && category._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title) + return true }) - ], - (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + }), + body('en_name') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .custom((value, {req}) => { + return BlogCategory.findOne({'blogCategory_details.en.name': value}).then(category => { + if (category && category._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title) + return true + }) + }) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - const data = { - blogCategory_details: { - fa: { - name: req.body.fa_name - }, - en: { - name: req.body.en_name - } - }, - updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') - } - BlogCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => { - if (err) console.log(err) - return res.json({message: v_m['fa'].response.success_save}) - }) - } + const data = { + blogCategory_details: { + fa: { + name: req.body.fa_name + }, + en: { + name: req.body.en_name + } + }, + updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + } + BlogCategory.findByIdAndUpdate(req.params.id, data, (err, oldData) => { + if (err) console.log(err) + return res.json({message: v_m['fa'].response.success_save}) + }) + } ] module.exports.delete = [ - (req, res) => { - BlogPost.find({category: req.params.id}, (err, posts) => { - if (err) console.log(err) - if (!posts.length) { - BlogCategory.findByIdAndDelete(req.params.id, (err) => { - if (err) return res.status(404).json({message: err}) - return res.json({message: v_m['fa'].response.success_save}) - }) - } else { - return res.status(500).json({message: 'نمیتوان دسته بندی هایی که دارای پست هستند را پاک کرد.'}) - } - }) - } + (req, res) => { + BlogPost.find({category: req.params.id}, (err, posts) => { + if (err) console.log(err) + if (!posts.length) { + BlogCategory.findByIdAndDelete(req.params.id, (err) => { + if (err) return res.status(404).json({message: err}) + return res.json({message: v_m['fa'].response.success_save}) + }) + } else { + return res.status(500).json({message: 'نمیتوان دسته بندی هایی که دارای پست هستند را پاک کرد.'}) + } + }) + } ] diff --git a/api/controllers/blogPostController.js b/api/controllers/blogPostController.js index f8ac86c..bd8d1c3 100644 --- a/api/controllers/blogPostController.js +++ b/api/controllers/blogPostController.js @@ -5,246 +5,246 @@ const fs = require('fs') const jimp = require('jimp') const v_m = require('../validation_messages') +// local variables +const shortDescriptionLength = 500 + +const coverWidth = 1920 +const coverHeight = 720 +const coverQuality = 70 + +const thumbWith = 460 +const thumbHeight = 320 + module.exports.create = [ - [ - // title - body('fa_title') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .isLength({max: 120}).withMessage(v_m['fa'].max_char.max120) - .bail() - .custom((value, {req}) => { - return BlogPost.findOne({'post_details.fa.title': value}).then(post => { - if (post) return Promise.reject(v_m['fa'].duplicated.title) - return true - }) - }), - body('en_title') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .isLength({max: 120}).withMessage(v_m['fa'].max_char.max120) - .bail() - .custom((value, {req}) => { - return BlogPost.findOne({'post_details.en.title': value}).then(post => { - if (post) return Promise.reject(v_m['fa'].duplicated.title) - return true - }) - }), - - // description - body('fa_description') - .notEmpty().withMessage(v_m['fa'].required.description), - body('en_description') - .notEmpty().withMessage(v_m['fa'].required.description), - - // short description - body('fa_short_description') - .notEmpty().withMessage(v_m['fa'].required.description) - .bail() - .isLength({max: 200}).withMessage(v_m['fa'].max_char.max200), - body('en_short_description') - .notEmpty().withMessage(v_m['fa'].required.description) - .bail() - .isLength({max: 200}).withMessage(v_m['fa'].max_char.max200), - - body('category') - .notEmpty().withMessage(v_m['fa'].required.category) - ], - (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - - let cover - let coverName - - // 460 X 320 - // 1920 x 720 - - if (req.files && req.files.cover) { - cover = req.files.cover - coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1] - } else { - return res.status(422).json({validation: {cover: {msg: v_m['fa'].required.cover}}}) - } - - jimp.read(cover.data) - .then(img => { - img - .cover(1920, 720) - .quality(70) - .write(`./static/uploads/images/blog/${coverName}`) - .resize(460, jimp.AUTO) - .cover(460, 320) - .write(`./static/uploads/images/blog/thumb_${coverName}`) + [ + // title + body('fa_title') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .isLength({max: 120}).withMessage(v_m['fa'].max_char.max120) + .bail() + .custom((value, {req}) => { + return BlogPost.findOne({'post_details.fa.title': value}).then(post => { + if (post) return Promise.reject(v_m['fa'].duplicated.title) + return true }) + }), + body('en_title') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .isLength({max: 120}).withMessage(v_m['fa'].max_char.max120) + .bail() + .custom((value, {req}) => { + return BlogPost.findOne({'post_details.en.title': value}).then(post => { + if (post) return Promise.reject(v_m['fa'].duplicated.title) + return true + }) + }), - const data = { - post_details: { - fa: { - title: req.body.fa_title, - description: req.body.fa_description, - short_description: req.body.fa_short_description - }, - en: { - title: req.body.en_title, - description: req.body.en_description, - short_description: req.body.en_short_description - } - }, - cover: coverName, - published: req.body.published, - category: req.body.category, - created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') - } + // description + body('fa_description') + .notEmpty().withMessage(v_m['fa'].required.description), + body('en_description') + .notEmpty().withMessage(v_m['fa'].required.description), - const post = new BlogPost(data) - post.save(err => { - if (err) console.log(err) - return res.json({message: v_m['fa'].response.success_save}) - }) - } + // short description + body('fa_short_description') + .notEmpty().withMessage(v_m['fa'].required.description), + body('en_short_description') + .notEmpty().withMessage(v_m['fa'].required.description), + + body('category') + .notEmpty().withMessage(v_m['fa'].required.category) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + + let cover + let coverName + + if (req.files && req.files.cover) { + cover = req.files.cover + coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1] + } else { + return res.status(422).json({validation: {cover: {msg: v_m['fa'].required.cover}}}) + } + + jimp.read(cover.data) + .then(img => { + img + .cover(coverWidth, coverHeight) + .quality(coverQuality) + .write(`./static/uploads/images/blog/${coverName}`) + .resize(thumbWith, jimp.AUTO) + .cover(thumbWith, thumbHeight) + .write(`./static/uploads/images/blog/thumb_${coverName}`) + }) + + const data = { + post_details: { + fa: { + title: req.body.fa_title, + description: req.body.fa_description, + short_description: req.body.fa_short_description.slice(0, shortDescriptionLength) + ' ... ' + }, + en: { + title: req.body.en_title, + description: req.body.en_description, + short_description: req.body.en_short_description.slice(0, shortDescriptionLength) + ' ... ' + } + }, + cover: coverName, + published: req.body.published, + category: req.body.category, + created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + } + + const post = new BlogPost(data) + post.save(err => { + if (err) console.log(err) + return res.json({message: v_m['fa'].response.success_save}) + }) + } ] module.exports.getAll = [ - (req, res) => { - BlogPost.find({}).sort({_id: -1}).exec((err, posts) => { - if (err) console.log(err) - return res.json(posts) - }) - } + (req, res) => { + BlogPost.find({}).sort({_id: -1}).exec((err, posts) => { + if (err) console.log(err) + return res.json(posts) + }) + } ] module.exports.getOne = [ - (req, res) => { - BlogPost.findById(req.params.id, (err, post) => { - if (err) console.log(err) - return res.json(post) - }) - } + (req, res) => { + BlogPost.findById(req.params.id, (err, post) => { + if (err) console.log(err) + return res.json(post) + }) + } ] module.exports.update = [ - [ - // title - body('fa_title') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .isLength({max: 120}).withMessage(v_m['fa'].max_char.max120) - .bail() - .custom((value, {req}) => { - return BlogPost.findOne({'post_details.fa.title': value}).then(post => { - if (post && post._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title) - return true - }) - }), - body('en_title') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .isLength({max: 120}).withMessage(v_m['fa'].max_char.max120) - .bail() - .custom((value, {req}) => { - return BlogPost.findOne({'post_details.en.title': value}).then(post => { - if (post && post._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title) - return true - }) - }), + [ + // title + body('fa_title') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .isLength({max: 120}).withMessage(v_m['fa'].max_char.max120) + .bail() + .custom((value, {req}) => { + return BlogPost.findOne({'post_details.fa.title': value}).then(post => { + if (post && post._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title) + return true + }) + }), + body('en_title') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .isLength({max: 120}).withMessage(v_m['fa'].max_char.max120) + .bail() + .custom((value, {req}) => { + return BlogPost.findOne({'post_details.en.title': value}).then(post => { + if (post && post._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.title) + return true + }) + }), - // description - body('fa_description') - .notEmpty().withMessage(v_m['fa'].required.description), - body('en_description') - .notEmpty().withMessage(v_m['fa'].required.description), + // description + body('fa_description') + .notEmpty().withMessage(v_m['fa'].required.description), + body('en_description') + .notEmpty().withMessage(v_m['fa'].required.description), - // short description - body('fa_short_description') - .notEmpty().withMessage(v_m['fa'].required.description) - .bail() - .isLength({max: 200}).withMessage(v_m['fa'].max_char.max200), - body('en_short_description') - .notEmpty().withMessage(v_m['fa'].required.description) - .bail() - .isLength({max: 200}).withMessage(v_m['fa'].max_char.max200), + // short description + body('fa_short_description') + .notEmpty().withMessage(v_m['fa'].required.description), + body('en_short_description') + .notEmpty().withMessage(v_m['fa'].required.description), - body('category') - .notEmpty().withMessage(v_m['fa'].required.category) - ], - (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + body('category') + .notEmpty().withMessage(v_m['fa'].required.category) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - const data = { - post_details: { - fa: { - title: req.body.fa_title, - description: req.body.fa_description, - short_description: req.body.fa_short_description - }, - en: { - title: req.body.en_title, - description: req.body.en_description, - short_description: req.body.en_short_description - } - }, - published: req.body.published, - category: req.body.category, - updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + const data = { + post_details: { + fa: { + title: req.body.fa_title, + description: req.body.fa_description, + short_description: req.body.fa_short_description.slice(0, shortDescriptionLength) + ' ... ' + }, + en: { + title: req.body.en_title, + description: req.body.en_description, + short_description: req.body.en_short_description.slice(0, shortDescriptionLength) + ' ... ' + } + }, + published: req.body.published, + category: req.body.category, + updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + } + + let cover + let coverName + + if (req.files && req.files.cover) { + cover = req.files.cover + coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1] + + data.cover = coverName + jimp.read(cover.data) + .then(img => { + img + .cover(coverWidth, coverHeight) + .quality(coverQuality) + .write(`./static/uploads/images/blog/${coverName}`) + .resize(thumbWith, jimp.AUTO) + .cover(thumbWith, thumbHeight) + .write(`./static/uploads/images/blog/thumb_${coverName}`) + }) + } + + BlogPost.findByIdAndUpdate(req.params.id, data, (err, oldData) => { + if (err) console.log(err) + if (cover && cover.data) { + fs.unlink(`./static/${oldData.cover}`, err => { + if (err) console.log(err) + }) + fs.unlink(`./static/${oldData.thumb}`, err => { + if (err) console.log(err) + }) } - - // 460 X 320 - // 1920 x 720 - - let cover - let coverName - - if (req.files && req.files.cover) { - cover = req.files.cover - coverName = 'blog_' + Date.now() + '.' + cover.mimetype.split('/')[1] - - data.cover = coverName - jimp.read(cover.data) - .then(img => { - img - .cover(1920, 720) - .write(`./static/uploads/images/blog/${coverName}`) - .resize(460, jimp.AUTO) - .cover(460, 320) - .write(`./static/uploads/images/blog/thumb_${coverName}`) - }) - } - - BlogPost.findByIdAndUpdate(req.params.id, data, (err, oldData) => { - if (err) console.log(err) - if (cover && cover.data) { - fs.unlink(`./static/${oldData.cover}`, err => { - if (err) console.log(err) - }) - fs.unlink(`./static/${oldData.thumb}`, err => { - if (err) console.log(err) - }) - } - return res.json({message: v_m['fa'].response.success_save}) + BlogPost.findById(oldData._id, (err, newData) => { + if (err) console.log(err) + return res.json(newData) }) - } + }) + } ] 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.thumb}`, err => { - if (err) console.log(err) - }) - return res.json({message: v_m['fa'].response.success_remove}) + (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.thumb}`, err => { + if (err) console.log(err) + }) + return res.json({message: v_m['fa'].response.success_remove}) + }) + } ] diff --git a/api/controllers/calculationModule.js b/api/controllers/calculationModule.js index 06e5ba5..389475d 100644 --- a/api/controllers/calculationModule.js +++ b/api/controllers/calculationModule.js @@ -2,34 +2,672 @@ const {body, validationResult} = require('express-validator') const v_m = require('../validation_messages') const validationMessages = { - fa: {}, - en: {} + fa: { + method: 'روش محاسبه را انتخاب کنید', + method_not_supported: 'روش انتخاب شده پشتیبانی نشده است', + gratingType: 'نوع گریتینک را انتخاب کنید', + gratingType_not_supported: 'نوع گریتینگ پشتیبانی نشده است', + loadType: 'نوع فشار را وارد کنید', + class: 'کلاس را انتخاب کنید', + pointedLoad: 'مقدار بار متمرکز را وارد کنید', + distributedLoad: 'مقدار بار گسترده را وارد کنید', + bearingBarThickness: 'ضخامت تسمه باربر را وارد کنید', + bearingBarPitch: 'گام تسمه باربر را انتخاب کنید', + bearingBarPitch_not_ok: 'مقدار گام تسمه باربر صحیح نیست', + crossBarPitch: 'گام تسمه رابط را تنخاب کنید', + crossBarPitch_not_ok: 'مقدار گام تسمه رابط صحیح نیست', + bearingBarHeight: 'ارتفاع تسمه باربر را انتخاب کنید', + bearingBarHeight_not_ok: 'مقدار ارتفاع تسمه باربر صحیح نیست', + clearSpan: 'مقدار دهنه را وارد کنید', + sigma_ok: 'تنش مجاز', + sigma_out_of_range: 'تنش خارج از حد مجاز', + deflection_ok: 'خیز مجاز', + deflection_out_of_range: 'خیز خارج از حد مجاز' + }, + en: { + method: 'Choose calculation method', + method_not_supported: 'Chosen calculation method not supported', + gratingType: 'Select the type of grating', + gratingType_not_supported: 'Grating type not supported', + loadType: 'Enter load type', + class: 'Select class', + pointedLoad: 'Enter the amount of pointed load', + distributedLoad: 'Enter the amount of distributed load', + bearingBarThickness: 'Enter bearing bar thickness', + bearingBarPitch: 'Select bearing bar pitch', + bearingBarPitch_not_ok: 'Bearing bar pitch value is incorrect', + crossBarPitch: 'Select cross bar pitch', + crossBarPitch_not_ok: 'Cross bar pitch value is incorrect', + bearingBarHeight: 'Select bearing bar height', + bearingBarHeight_not_ok: 'Bearing bar height is incorrect', + clearSpan: 'Enter clear span', + sigma_ok: 'Tension OK', + sigma_out_of_range: 'Tension Out Of Range', + deflection_ok: 'Deflection OK', + deflection_out_of_range: 'Deflection Out Of Range' + } } -module.exports = [ - [ - body('method') - .notEmpty().withMessage(), - body('type') - .notEmpty().withMessage(), - body('class') - .notEmpty().withMessage(), - body('pointLoad') - .notEmpty().withMessage(), - body('distributedLoad') - .notEmpty().withMessage(), - body('bearingBarPitch') - .notEmpty().withMessage(), - body('crossBarPitCh') - .notEmpty().withMessage(), - body('clearSpan') - .notEmpty().withMessage(), - body('bearingBarThickness') - .notEmpty().withMessage(), - body('bearingBarHeight') - .notEmpty().withMessage() - ], - (req, res) => { +const values = { + // ArakRail products + bearingBarPitch_forge: [30, 35, 41, 50], + bearingBarPitch_pressured: [11, 22, 33, 44, 50, 55], + // defined in formula + crossBarPitch_forge: [38, 50, 76, 100], + crossBarPitch_pressured: [11, 22, 33, 44, 50, 55, 66, 77, 88, 100], + // defined in formula + bearingBarHeight: [20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100] +} - } +function relativeBearingBarHeight(gratingType, crossBarPitch) { + // defined in formula + bearingBarHeight = values.bearingBarHeight + const CBPitch = Number(crossBarPitch) + + if (gratingType === 'forge') { + if (CBPitch === 38) return bearingBarHeight.filter(item => item <= 80) + else return bearingBarHeight.filter(item => item <= 60) + } else if (gratingType === 'pressured') { + if ( + CBPitch === 11 || + CBPitch === 22 || + CBPitch === 55 || + CBPitch === 77 || + CBPitch === 88 + ) return bearingBarHeight.filter(item => item <= 60) + else if ( + CBPitch === 33 || + CBPitch === 44 || + CBPitch === 50 || + CBPitch === 66 || + CBPitch === 100 + ) return bearingBarHeight + } +} + +module.exports.calculate = [ + [ + body('method') + .notEmpty().withMessage((value, {req}) => { + return validationMessages[req.body.locale].method + }) + .bail() + .custom((value, {req}) => { + if (value === 'custom' || value === 'classified') return true + else return Promise.reject(validationMessages[req.body.locale].method_not_supported) + }), + body('gratingType') + .notEmpty().withMessage((value, {req}) => { + return validationMessages[req.body.locale].gratingType + }) + .bail() + .custom((value, {req}) => { + if (value === 'forge' || value === 'pressured') return true + else return Promise.reject(validationMessages[req.body.locale].gratingType_not_supported) + }), + body('loadType') + .custom((value, {req}) => { + if (req.body.method === 'custom') { + if (value === 'pointedLoad' || value === 'distributedLoad') return true + else return Promise.reject(validationMessages[req.body.locale].loadType) + } else return true + }), + body('vehicleClass') + .custom((value, {req}) => { + if (req.body.method === 'classified') { + const classes = ['class1', 'class2', 'class3', 'class4', 'FL1', 'FL2', 'FL3', 'FL4', 'FL5', 'FL6'] + if (classes.includes(value)) return true + else return Promise.reject(validationMessages[req.body.locale].class) + } else return true + }), + body('pointedLoadValue') + .custom((value, {req}) => { + if (req.body.method === 'custom') { + if (req.body.loadType === 'pointedLoad' && !value) return Promise.reject(validationMessages[req.body.locale].pointedLoad) + else return true + } else return true + }) + .bail() + .if((value, {req}) => req.body.method === 'custom' && req.body.loadType === 'pointedLoad') + .isNumeric().withMessage((value, {req}) => { + return v_m[req.body.locale].format.number + }), + body('distributedLoadValue') + .custom((value, {req}) => { + if (req.body.method === 'custom') { + if (req.body.loadType === 'distributedLoad' && !value) return Promise.reject(validationMessages[req.body.locale].distributedLoad) + else return true + } else return true + }) + .bail() + .if((value, {req}) => req.body.method === 'custom' && req.body.loadType === 'distributedLoad') + .isNumeric().withMessage((value, {req}) => { + return v_m[req.body.locale].format.number + }), + body('bearingBarThickness') + .notEmpty().withMessage((value, {req}) => { + return validationMessages[req.body.locale].bearingBarThickness + }) + .bail() + .isNumeric().withMessage((value, {req}) => { + return v_m[req.body.locale].format.number + }), + + + body('bearingBarPitch') + .notEmpty().withMessage((value, {req}) => { + return validationMessages[req.body.locale].bearingBarPitch + }) + .bail() + .isNumeric().withMessage((value, {req}) => { + return v_m[req.body.locale].format.number + }) + .bail() + .custom((value, {req}) => { + if (req.body.gratingType === 'forge') { + if (values.bearingBarPitch_forge.includes(Number(value))) return true + else return Promise.reject(validationMessages[req.body.locale].bearingBarPitch_not_ok) + } else { + if (values.bearingBarPitch_pressured.includes(Number(value))) return true + else return Promise.reject(validationMessages[req.body.locale].bearingBarPitch_not_ok) + } + }), + + body('crossBarPitch') + .notEmpty().withMessage((value, {req}) => { + return validationMessages[req.body.locale].crossBarPitch + }) + .bail() + .isNumeric().withMessage((value, {req}) => { + return v_m[req.body.locale].format.number + }) + .bail() + .custom((value, {req}) => { + if (req.body.gratingType === 'forge') { + if (values.crossBarPitch_forge.includes(Number(value))) return true + else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok) + } else { + if (values.crossBarPitch_pressured.includes(Number(value))) return true + else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok) + } + }), + + body('bearingBarHeight') + .notEmpty().withMessage((value, {req}) => { + return validationMessages[req.body.locale].bearingBarHeight + }) + .bail() + .isNumeric().withMessage((value, {req}) => { + return v_m[req.body.locale].format.number + }) + .bail() + .custom((value, {req}) => { + if (relativeBearingBarHeight(req.body.gratingType, req.body.crossBarPitch).includes(Number(value))) return true + else return Promise.reject(validationMessages[req.body.locale].bearingBarHeight_not_ok) + }), + + body('clearSpan') + .notEmpty().withMessage((value, {req}) => { + return validationMessages[req.body.locale].clearSpan + }) + .bail() + .isNumeric().withMessage((value, {req}) => { + return v_m[req.body.locale].format.number + }) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + + let method = req.body.method + let gratingType = req.body.gratingType + let loadType = req.body.loadType + let vehicleClass = req.body.vehicleClass + + let bearingBarHeight = req.body.bearingBarHeight + let bearingBarThickness = req.body.bearingBarThickness + let bearingBarPitch = req.body.bearingBarPitch + let crossBarPitch = req.body.crossBarPitch + let clearSpan = req.body.clearSpan + let locale = req.body.locale + + + ///////// classified vehicles + const vehiclesClasses = { + 'class1': { + distributedLoad: 6 + }, + 'class2': { + pointedLoad: 10, + c4: 200, + d4: 200 + }, + 'class3': { + pointedLoad: 30, + c4: 200, + d4: 400 + }, + 'class4': { + pointedLoad: 90, + c4: 250, + d4: 600 + }, + 'FL1': { + pointedLoad: 26, + c4: 130, + d4: 130 + }, + 'FL2': { + pointedLoad: 40, + c4: 150, + d4: 175 + }, + 'FL3': { + pointedLoad: 63, + c4: 200, + d4: 200 + }, + 'FL4': { + pointedLoad: 90, + c4: 200, + d4: 300 + }, + 'FL5': { + pointedLoad: 140, + c4: 200, + d4: 375 + }, + 'FL6': { + pointedLoad: 170, + c4: 200, + d4: 450 + }, + } + + ///////// pointed load + function pointedLoad() { + // static variables + const forge = gratingType === 'forge' + const custom = method === 'custom' + + // computing m | c4 | d4 | pointedLoadValue + function m_pressured(bearingBarHeight, crossBarPitch) { + const CBPitch = Number(crossBarPitch) + const BBHeight = Number(bearingBarHeight) + + if (BBHeight === 20) { + if (CBPitch === 11) return 4.00 + if (CBPitch === 22) return 4.00 + if (CBPitch === 33) return 3.33 + if (CBPitch === 44) return 2.50 + if (CBPitch === 50) return 2.22 + if (CBPitch === 55) return 2.00 + if (CBPitch === 66) return 1.68 + if (CBPitch === 77) return 1.43 + if (CBPitch === 88) return 1.25 + if (CBPitch === 100) return 1.11 + } else if (BBHeight === 25) { + if (CBPitch === 11) return 3.85 + if (CBPitch === 22) return 3.85 + if (CBPitch === 33) return 3.25 + if (CBPitch === 44) return 2.45 + if (CBPitch === 50) return 2.17 + if (CBPitch === 55) return 1.95 + if (CBPitch === 66) return 1.62 + if (CBPitch === 77) return 1.40 + if (CBPitch === 88) return 1.21 + if (CBPitch === 100) return 1.08 + } else if (BBHeight === 30) { + if (CBPitch === 11) return 3.80 + if (CBPitch === 22) return 3.77 + if (CBPitch === 33) return 3.17 + if (CBPitch === 44) return 2.40 + if (CBPitch === 50) return 2.15 + if (CBPitch === 55) return 1.90 + if (CBPitch === 66) return 1.58 + if (CBPitch === 77) return 1.35 + if (CBPitch === 88) return 1.19 + if (CBPitch === 100) return 1.06 + } else if (BBHeight === 35) { + if (CBPitch === 11) return 3.75 + if (CBPitch === 22) return 3.75 + if (CBPitch === 33) return 3.08 + if (CBPitch === 44) return 2.32 + if (CBPitch === 50) return 2.05 + if (CBPitch === 55) return 1.86 + if (CBPitch === 66) return 1.54 + if (CBPitch === 77) return 1.33 + if (CBPitch === 88) return 1.17 + if (CBPitch === 100) return 1.02 + } else if (BBHeight === 40) { + if (CBPitch === 11) return 3.70 + if (CBPitch === 22) return 3.65 + if (CBPitch === 33) return 3.00 + if (CBPitch === 44) return 2.25 + if (CBPitch === 50) return 2.00 + if (CBPitch === 55) return 1.80 + if (CBPitch === 66) return 1.52 + if (CBPitch === 77) return 1.28 + if (CBPitch === 88) return 1.12 + if (CBPitch === 100) return 1.01 + } else if (BBHeight === 45) { + if (CBPitch === 11) return 3.65 + if (CBPitch === 22) return 3.50 + if (CBPitch === 33) return 2.92 + if (CBPitch === 44) return 2.18 + if (CBPitch === 50) return 1.95 + if (CBPitch === 55) return 1.75 + if (CBPitch === 66) return 1.46 + if (CBPitch === 77) return 1.25 + if (CBPitch === 88) return 1.09 + if (CBPitch === 100) return 0.97 + } else if (BBHeight === 50) { + if (CBPitch === 11) return 3.45 + if (CBPitch === 22) return 3.41 + if (CBPitch === 33) return 2.83 + if (CBPitch === 44) return 2.10 + if (CBPitch === 50) return 1.88 + if (CBPitch === 55) return 1.69 + if (CBPitch === 66) return 1.42 + if (CBPitch === 77) return 1.22 + if (CBPitch === 88) return 1.06 + if (CBPitch === 100) return 0.94 + } else if (BBHeight === 55) { + if (CBPitch === 11) return 3.28 + if (CBPitch === 22) return 3.26 + if (CBPitch === 33) return 2.75 + if (CBPitch === 44) return 2.08 + if (CBPitch === 50) return 1.84 + if (CBPitch === 55) return 1.66 + if (CBPitch === 66) return 1.39 + if (CBPitch === 77) return 1.18 + if (CBPitch === 88) return 1.04 + if (CBPitch === 100) return 0.92 + } else if (BBHeight === 60) { + if (CBPitch === 11) return 3.20 + if (CBPitch === 22) return 3.18 + if (CBPitch === 33) return 2.67 + if (CBPitch === 44) return 1.98 + if (CBPitch === 50) return 1.76 + if (CBPitch === 55) return 1.59 + if (CBPitch === 66) return 1.35 + if (CBPitch === 77) return 1.14 + if (CBPitch === 88) return 0.99 + if (CBPitch === 100) return 0.89 + } else if (BBHeight === 65) { + if (CBPitch === 33) return 2.58 + if (CBPitch === 44) return 1.93 + if (CBPitch === 50) return 1.71 + if (CBPitch === 66) return 1.30 + if (CBPitch === 100) return 0.86 + } else if (BBHeight === 70) { + if (CBPitch === 33) return 2.50 + if (CBPitch === 44) return 1.88 + if (CBPitch === 50) return 1.66 + if (CBPitch === 66) return 1.25 + if (CBPitch === 100) return 0.83 + } else if (BBHeight === 75) { + if (CBPitch === 33) return 2.42 + if (CBPitch === 44) return 1.82 + if (CBPitch === 50) return 1.62 + if (CBPitch === 66) return 1.20 + if (CBPitch === 100) return 0.81 + } else if (BBHeight === 80) { + if (CBPitch === 33) return 2.33 + if (CBPitch === 44) return 1.75 + if (CBPitch === 50) return 1.58 + if (CBPitch === 66) return 1.15 + if (CBPitch === 100) return 0.78 + } else if (BBHeight === 85) { + if (CBPitch === 33) return 2.25 + if (CBPitch === 44) return 1.71 + if (CBPitch === 50) return 1.52 + if (CBPitch === 66) return 1.13 + if (CBPitch === 100) return 0.75 + } else if (BBHeight === 90) { + if (CBPitch === 33) return 2.17 + if (CBPitch === 44) return 1.67 + if (CBPitch === 50) return 1.45 + if (CBPitch === 66) return 1.11 + if (CBPitch === 100) return 0.72 + } else if (BBHeight === 95) { + if (CBPitch === 33) return 2.08 + if (CBPitch === 44) return 1.59 + if (CBPitch === 50) return 1.39 + if (CBPitch === 66) return 1.05 + if (CBPitch === 100) return 0.69 + } else if (BBHeight === 100) { + if (CBPitch === 33) return 2.00 + if (CBPitch === 44) return 1.50 + if (CBPitch === 50) return 1.33 + if (CBPitch === 66) return 0.99 + if (CBPitch === 100) return 0.66 + } + } + + function m_forge(bearingBarHeight, crossBarPitch) { + const CBPitch = Number(crossBarPitch) + const BBHeight = Number(bearingBarHeight) + + if (BBHeight === 20) { + if (CBPitch === 38) return 2.25 + if (CBPitch === 50) return 1.35 + if (CBPitch === 76) return 0.81 + if (CBPitch === 100) return 0.52 + } else if (BBHeight === 25) { + if (CBPitch === 38) return 2.19 + if (CBPitch === 50) return 1.28 + if (CBPitch === 76) return 0.77 + if (CBPitch === 100) return 0.52 + } else if (BBHeight === 30) { + if (CBPitch === 38) return 2.13 + if (CBPitch === 50) return 1.25 + if (CBPitch === 76) return 0.75 + if (CBPitch === 100) return 0.48 + } else if (BBHeight === 35) { + if (CBPitch === 38) return 2.06 + if (CBPitch === 50) return 1.20 + if (CBPitch === 76) return 0.71 + if (CBPitch === 100) return 0.47 + } else if (BBHeight === 40) { + if (CBPitch === 38) return 2.00 + if (CBPitch === 50) return 1.17 + if (CBPitch === 76) return 0.67 + if (CBPitch === 100) return 0.45 + } else if (BBHeight === 45) { + if (CBPitch === 38) return 1.94 + if (CBPitch === 50) return 1.11 + if (CBPitch === 76) return 0.65 + if (CBPitch === 100) return 0.43 + } else if (BBHeight === 50) { + if (CBPitch === 38) return 1.88 + if (CBPitch === 50) return 1.05 + if (CBPitch === 76) return 0.62 + if (CBPitch === 100) return 0.40 + } else if (BBHeight === 55) { + if (CBPitch === 38) return 1.81 + if (CBPitch === 50) return 1.03 + if (CBPitch === 76) return 0.61 + if (CBPitch === 100) return 0.38 + } else if (BBHeight === 60) { + if (CBPitch === 38) return 1.75 + if (CBPitch === 50) return 1.00 + if (CBPitch === 76) return 0.59 + if (CBPitch === 100) return 0.36 + } else if (BBHeight === 65) { + if (CBPitch === 38) return 1.69 + } else if (BBHeight === 70) { + if (CBPitch === 38) return 1.63 + } else if (BBHeight === 75) { + if (CBPitch === 38) return 1.56 + } else if (BBHeight === 80) { + if (CBPitch === 38) return 1.50 + } + } + + let m = () => { + if (forge) return m_forge(bearingBarHeight, crossBarPitch) + else return m_pressured(bearingBarHeight, crossBarPitch) + } + + const c4 = () => { + if (custom) return 200 + else return vehiclesClasses[vehicleClass].c4 + } + const d4 = () => { + if (custom) return 200 + else return vehiclesClasses[vehicleClass].d4 + } + const pointedLoadValue = () => { + if (custom) return req.body.pointedLoadValue + else return vehiclesClasses[vehicleClass].pointedLoad + } + /////////////////////////////////////////////////////////////// computed variables + const MaxM = (((pointedLoadValue() * 1000) * (clearSpan - (d4() / 2))) / 4) * 1.5 + const n = (c4() / bearingBarPitch) + m() + const W = () => { + const temp = (((bearingBarThickness * Math.pow(bearingBarHeight, 2)) / 6) * n) + return forge ? temp : (temp * 0.9) + } + const sigma = MaxM / W() + const L = () => { + const temp = (((bearingBarThickness * (Math.pow(bearingBarHeight, 3))) / 12) * n) + return forge ? temp : (temp * 0.9) + } + const D = ((pointedLoadValue() * 1000) / (384 * 210000 * L())) * ((8 * Math.pow(clearSpan, 3)) - (4 * clearSpan * Math.pow(d4(), 2)) + (Math.pow(d4(), 3))) + + // console.log('m =' + m()) + // console.log('c4 =' + c4()) + // console.log('d4 =' + d4()) + // console.log('pointedLoadValue =' + pointedLoadValue()) + // console.log('MaxM =' + MaxM) + // console.log('n =' + n) + // console.log('W =' + W()) + // console.log('sigma =' + sigma) + // console.log('L =' + L()) + // console.log('D =' + D) + //////////////////////////////////////////////////////////////// calculate result + const result = { + sigma: null, + sigmaStatus: null, + deflection: null, + deflectionStatus: null + } + if (sigma < 235) { + result.sigma = validationMessages[locale].sigma_ok + result.sigmaStatus = true + } else { + result.sigma = validationMessages[locale].sigma_out_of_range + result.sigmaStatus = false + } + + if (D < (clearSpan / 200)) { + result.deflection = validationMessages[locale].deflection_ok + result.deflectionStatus = true + } else { + result.deflection = validationMessages[locale].deflection_out_of_range + result.deflectionStatus = false + } + return result + } + + ///////// distributed load + function distributedLoad() { + // static variables + const forge = gratingType === 'forge' + const custom = method === 'custom' + // computing distributedLoadValue + const distributedLoadValue = () => { + if (custom) return req.body.distributedLoadValue + else return vehiclesClasses[vehicleClass].distributedLoad + } + ////////////////////////////////////////////////////////////////// computed variables + const MaxM = (((distributedLoadValue() * 10) * bearingBarPitch * Math.pow(clearSpan, 2)) / 80000) * 1.5 + const W = () => { + const temp = (bearingBarThickness * Math.pow(bearingBarHeight, 2)) / 6 + return forge ? temp : (temp * 0.9) + } + const sigma = MaxM / W() + const L = () => { + const temp = (bearingBarThickness * Math.pow(bearingBarHeight, 3)) / 12 + return forge ? temp : (temp * 0.9) + } + const D = (5 * distributedLoadValue() * bearingBarPitch * Math.pow(clearSpan, 4)) / (384 * 21000 * L() * Math.pow(10, 4)) + ////////////////////////////////////////////////////////////////// calculate result + const result = { + sigma: null, + sigmaStatus: null, + deflection: null, + deflectionStatus: null + } + if (sigma < 235) { + result.sigma = validationMessages[locale].sigma_ok + result.sigmaStatus = true + } else { + result.sigma = validationMessages[locale].sigma_out_of_range + result.sigmaStatus = false + } + + if (D < (clearSpan / 200)) { + result.deflection = validationMessages[locale].deflection_ok + result.deflectionStatus = true + } else { + result.deflection = validationMessages[locale].deflection_out_of_range + result.deflectionStatus = false + } + return result + } + + ////////////////////////////////////////////// calculate + if (method === 'custom') { + if (loadType === 'pointedLoad') return res.json(pointedLoad()) + else return res.json(distributedLoad()) + } else if (method === 'classified') { + if (vehicleClass === 'class1') return res.json(distributedLoad()) + else return res.json(pointedLoad()) + } else return res.json({message: 'unsupported entry'}) + + } +] + + +module.exports.getRelativeValues = [ + [ + body('gratingType') + .notEmpty().withMessage((value, {req}) => { + return validationMessages[req.body.locale].gratingType + }) + .bail() + .custom((value, {req}) => { + if (value === 'forge' || value === 'pressured') return true + else Promise.reject(validationMessages[req.body.locale].gratingType_not_supported) + }), + + body('crossBarPitch') + .notEmpty().withMessage((value, {req}) => { + return validationMessages[req.body.locale].crossBarPitch + }) + .bail() + .custom((value, {req}) => { + if (req.body.gratingType === 'forge') { + if (values.crossBarPitch_forge.includes(Number(value))) return true + else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok) + } else { + if (values.crossBarPitch_pressured.includes(Number(value))) return true + else return Promise.reject(validationMessages[req.body.locale].crossBarPitch_not_ok) + } + }) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json(errors.mapped()) + return res.json(relativeBearingBarHeight(req.body.gratingType, req.body.crossBarPitch)) + } +] + + +module.exports.getValues = [ + (req, res) => { + return res.json(values) + } ] diff --git a/api/controllers/historyController.js b/api/controllers/historyController.js index b0b7049..f6cd288 100644 --- a/api/controllers/historyController.js +++ b/api/controllers/historyController.js @@ -5,162 +5,168 @@ const jimp = require('jimp') const fs = require('fs') const v_m = require('../validation_messages') +// local variables +const imageWidth = 648 +const imageHeight = 443 +const imageQuality = 100 module.exports.create = [ - [ - body('fa_title') - .notEmpty().withMessage(v_m['fa'].required.title), + [ + body('fa_title') + .notEmpty().withMessage(v_m['fa'].required.title), - body('en_title') - .notEmpty().withMessage(v_m['fa'].required.title), + body('en_title') + .notEmpty().withMessage(v_m['fa'].required.title), - body('year') - .notEmpty().withMessage(v_m['fa'].required.date) - .bail() - .isNumeric().withMessage(v_m['fa'].format.number) - .bail() - .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4) - .bail() - .isLength({max: 4}).withMessage(v_m['fa'].max_char.max4) - ], - (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - if (!req.files || !req.files.image) return res.status(422).json({validation: {image: {msg: v_m['fa'].required.image}}}) + body('year') + .notEmpty().withMessage(v_m['fa'].required.date) + .bail() + .isNumeric().withMessage(v_m['fa'].format.number) + .bail() + .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4) + .bail() + .isLength({max: 4}).withMessage(v_m['fa'].max_char.max4) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + if (!req.files || !req.files.image) return res.status(422).json({validation: {image: {msg: v_m['fa'].required.image}}}) - const fileName = 'history_' + Date.now() + '.' + req.files.image.mimetype.split('/')[1] + const fileName = 'history_' + Date.now() + '.' + req.files.image.mimetype.split('/')[1] - const data = { - image: fileName, - year: Number(req.body.year), - history_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') - } + const data = { + image: fileName, + year: Number(req.body.year), + history_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') + } - jimp.read(req.files.image.data) - .then(img => { - img - .resize(380, jimp.AUTO) - .cover(380, 260) - .write(`./static/uploads/images/history/${fileName}`, cb => { - const history = new History(data) - history.save(err => { - if (err) console.log(err) - return res.json(v_m['fa'].response.success_save) - }) - }) - }) - .catch(err => { - console.log(err) - }) - } + jimp.read(req.files.image.data) + .then(img => { + img + .resize(imageWidth, jimp.AUTO) + .cover(imageWidth, imageHeight) + .quality(imageQuality) + .write(`./static/uploads/images/history/${fileName}`, cb => { + const history = new History(data) + history.save(err => { + if (err) console.log(err) + return res.json(v_m['fa'].response.success_save) + }) + }) + }) + .catch(err => { + console.log(err) + }) + } ] module.exports.getAll = [ - (req, res) => { - History.find({}).sort({year: 1}).exec((err, data) => { - if (err) console.log(err) - return res.json(data) - }) - } + (req, res) => { + History.find({}).sort({year: 1}).exec((err, data) => { + if (err) console.log(err) + return res.json(data) + }) + } ] module.exports.getOne = [ - (req, res) => { - History.findById(req.params.id, (err, data) => { - if (err) return res.status(404).json(err) - return res.json(data) - }) - } + (req, res) => { + History.findById(req.params.id, (err, data) => { + if (err) return res.status(404).json(err) + return res.json(data) + }) + } ] module.exports.update = [ - [ - body('fa_title') - .notEmpty().withMessage(v_m['fa'].required.title), + [ + body('fa_title') + .notEmpty().withMessage(v_m['fa'].required.title), - body('en_title') - .notEmpty().withMessage(v_m['fa'].required.title), + body('en_title') + .notEmpty().withMessage(v_m['fa'].required.title), - body('year') - .notEmpty().withMessage(v_m['fa'].required.date) - .bail() - .isNumeric().withMessage(v_m['fa'].format.number) - .bail() - .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4) - .bail() - .isLength({max: 4}).withMessage(v_m['fa'].max_char.max4) - ], - (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + body('year') + .notEmpty().withMessage(v_m['fa'].required.date) + .bail() + .isNumeric().withMessage(v_m['fa'].format.number) + .bail() + .isLength({min: 4}).withMessage(v_m['fa'].min_char.min4) + .bail() + .isLength({max: 4}).withMessage(v_m['fa'].max_char.max4) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - const data = { - year: Number(req.body.year), - history_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 = { + year: Number(req.body.year), + history_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 && req.files.image) { - let fileName = 'history_' + Date.now() + '.' + req.files.image.mimetype.split('/')[1] - data.image = fileName - jimp.read(req.files.image.data) - .then(img => { - img - .resize(380, jimp.AUTO) - .cover(380, 260) - .write(`./static/uploads/images/history/${fileName}`, cb => { - History.findByIdAndUpdate(req.params.id, data, (err, oldData) => { - if (err) console.log(err) - fs.unlink(`./static/${oldData.image}`, err => { - if (err) console.log(err) - return res.json(v_m['fa'].response.success_save) - }) - }) + if (req.files && req.files.image) { + let fileName = 'history_' + Date.now() + '.' + req.files.image.mimetype.split('/')[1] + data.image = fileName + jimp.read(req.files.image.data) + .then(img => { + img + .resize(imageWidth, jimp.AUTO) + .cover(imageWidth, imageHeight) + .quality(imageQuality) + .write(`./static/uploads/images/history/${fileName}`, cb => { + History.findByIdAndUpdate(req.params.id, data, (err, oldData) => { + if (err) console.log(err) + fs.unlink(`./static/${oldData.image}`, err => { + if (err) console.log(err) + return res.json(v_m['fa'].response.success_save) }) - }) - .catch(err => { - console.log(err) - }) - } else { - History.findByIdAndUpdate(req.params.id, data, (err, oldData) => { - if (err) console.log(err) - return res.json(v_m['fa'].response.success_save) + }) + }) }) - } - } + .catch(err => { + console.log(err) + }) + } else { + History.findByIdAndUpdate(req.params.id, data, (err, oldData) => { + if (err) console.log(err) + return res.json(v_m['fa'].response.success_save) + }) + } + } ] module.exports.delete = [ - (req, res) => { - History.findByIdAndDelete(req.params.id, (err, data) => { - if (err) console.log(err) - fs.unlink(`./static/${data.image}`, err => { - if (err) console.log(err) - return res.json(v_m['fa'].response.success_remove) - }) + (req, res) => { + History.findByIdAndDelete(req.params.id, (err, data) => { + if (err) console.log(err) + fs.unlink(`./static/${data.image}`, err => { + if (err) console.log(err) + return res.json(v_m['fa'].response.success_remove) }) - } + }) + } ] diff --git a/api/controllers/mainCatalogController.js b/api/controllers/mainCatalogController.js index de16668..a0b82c4 100644 --- a/api/controllers/mainCatalogController.js +++ b/api/controllers/mainCatalogController.js @@ -4,47 +4,49 @@ const v_m = require('../validation_messages') const fs = require('fs') module.exports.create = [ - (req, res) => { - if (!req.files || !req.files.pdf) return res.status(422).json({validation: {pdf: {msg: v_m['fa'].required.file}}}) - if (req.files.pdf.mimetype.split('/')[1] !== 'pdf') return res.status(422).json({validation: {pdf: {msg: v_m['fa'].file_types.pdf}}}) + (req, res) => { + if (!req.files || !req.files.pdf) return res.status(422).json({validation: {pdf: {msg: v_m['fa'].required.file}}}) + if (req.files.pdf.mimetype.split('/')[1] !== 'pdf') return res.status(422).json({validation: {pdf: {msg: v_m['fa'].file_types.pdf}}}) - MainCatalog.find({}, (err, catalogs) => { - if (catalogs.length) { - let firstFile = catalogs[0] - fs.unlink(`./static/${firstFile.file}`, err => { - if (err) console.log(err) - firstFile.file = req.files.pdf.name - firstFile.created_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') - firstFile.save((err1, data) => { - if (err1) console.log(err1) - req.files.pdf.mv(`./static/uploads/pdf/${req.files.pdf.name}`) - return res.json(firstFile) - }) + MainCatalog.find({}, (err, catalogs) => { + if (catalogs.length) { + let firstFile = catalogs[0] - }) - } else { - new MainCatalog({ - file: req.files.pdf.name, - created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') - }).save((err, data) => { - if (err) console.log(err) - req.files.pdf.mv(`./static/uploads/pdf/${req.files.pdf.name}`) - return res.json(data) - }) - } - }) + if (firstFile.file[req.body.locale]) fs.unlink(`./static/${firstFile.file[req.body.locale]}`, err => { + if (err) console.log(err) + }) - } + firstFile.file[req.body.locale] = req.body.locale + '_' + req.files.pdf.name + firstFile.updated_at = dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + firstFile.save((err1, data) => { + if (err1) console.log(err1) + req.files.pdf.mv(`./static/uploads/pdf/${req.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 + + new MainCatalog(data).save((err, data) => { + if (err) console.log(err) + req.files.pdf.mv(`./static/uploads/pdf/${req.body.locale}_${req.files.pdf.name}`) + return res.json(data) + }) + } + }) + + } ] - module.exports.get = [ - (req, res) => { - MainCatalog.find({}, (err, catalog) => { - if (err) console.log(err) - if (catalog.length) return res.json(catalog[0]) - else return res.json({}) - }) - } + (req, res) => { + MainCatalog.find({}, (err, catalog) => { + if (err) console.log(err) + if (catalog.length) return res.json(catalog[0]) + else return res.json({}) + }) + } ] diff --git a/api/controllers/productCategoryController.js b/api/controllers/productCategoryController.js index 8f712ab..b42994b 100644 --- a/api/controllers/productCategoryController.js +++ b/api/controllers/productCategoryController.js @@ -5,101 +5,102 @@ const dateformat = require('dateformat') const v_m = require('../validation_messages') module.exports.create = [ - [ - body('fa_name') - .notEmpty().withMessage(v_m['fa'].required.title), + [ + body('fa_name') + .notEmpty().withMessage(v_m['fa'].required.title), - body('en_name') - .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_name') + .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 = { - category_details: { - fa: { - name: req.body.fa_name - }, - en: { - name: req.body.en_name - } - }, - created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') - } + const data = { + category_details: { + fa: { + name: req.body.fa_name + }, + en: { + name: req.body.en_name + } + }, + created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + } - const category = new ProductCategory(data) - category.save(err => { - if (err) return res.status(500).json({message: err}) - return res.json({message: v_m['fa'].response.success_save}) - }) - } + const category = new ProductCategory(data) + category.save(err => { + if (err) return res.status(500).json({message: err}) + return res.json({message: v_m['fa'].response.success_save}) + }) + } ] module.exports.getAll = [ - (req, res) => { - ProductCategory.find({}, (err, categories) => { - if (err) return res.status(500).json({message: err}) - return res.json(categories) - }) - } + (req, res) => { + ProductCategory.find({}, (err, categories) => { + if (err) return res.status(500).json({message: err}) + return res.json(categories) + }) + } ] module.exports.getOne = [ - (req, res) => { - ProductCategory.findById(req.params.id, (err, category) => { - if (err) console.log(err) - return res.json(category) - }) - } + (req, res) => { + ProductCategory.findById(req.params.id, (err, category) => { + if (err) console.log(err) + return res.json(category) + }) + } ] module.exports.update = [ - [ - body('fa_name') - .notEmpty().withMessage(v_m['fa'].required.title), + [ + body('fa_name') + .notEmpty().withMessage(v_m['fa'].required.title), - body('en_name') - .notEmpty().withMessage(v_m['fa'].required.title) - ], - (req, res) => { - // check validation results - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + body('en_name') + .notEmpty().withMessage(v_m['fa'].required.title) + ], + (req, res) => { + // check validation results + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - const data = { - category_details: { - fa: { - name: req.body.fa_name - }, - en: { - name: req.body.en_name - } - } - } + const data = { + category_details: { + fa: { + name: req.body.fa_name + }, + en: { + name: req.body.en_name + } + }, + updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + } - ProductCategory.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}) - }) - } + ProductCategory.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}) + }) + } ] module.exports.delete = [ - (req, res) => { - Product.findOne({category: req.params.id}, (err, product) => { - if (err) console.log(err) - if (product) return res.status(400).json({message: 'این دسته بندی دارای محصول است.'}) - else { - ProductCategory.findByIdAndDelete(req.params.id, (err, category) => { - if (err) return res.status(404).json({message: err}) - return res.json({message: v_m['fa'].response.success_remove}) - }) - } - }) - } + (req, res) => { + Product.findOne({category: req.params.id}, (err, product) => { + if (err) console.log(err) + if (product) return res.status(400).json({message: 'این دسته بندی دارای محصول است.'}) + else { + ProductCategory.findByIdAndDelete(req.params.id, (err, category) => { + if (err) return res.status(404).json({message: err}) + return res.json({message: v_m['fa'].response.success_remove}) + }) + } + }) + } ] diff --git a/api/controllers/productController.js b/api/controllers/productController.js index 1017a47..714fb54 100644 --- a/api/controllers/productController.js +++ b/api/controllers/productController.js @@ -5,598 +5,684 @@ const jimp = require('jimp') const fs = require('fs') const v_m = require('../validation_messages') +// local variables +const shortDescriptionLength = 150 + +const coverWidth = 1010 +const coverHeight = 534 +const coverQuality = 100 + +const thumbWidth = 360 +const thumbHeight = 294 +const thumbQuality = 70 + +const moreSectionWidth = 778 +const moreSectionHeight = 395 +const moreSectionQuality = 70 + +const renderImageWidth = 300 +const renderImageHeight = 300 +const renderImageQuality = 70 + +const chartImageQuality = 100 + ////////////////////////////////////////// products controllers module.exports.createProduct = [ - [ - body('fa_name') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .custom((value, {req}) => { - return Product.findOne({'product_details.fa.name': value}) - .then(product => { - if (product) return Promise.reject(v_m['fa'].duplicated.name) - else return true - }) - }), + [ + body('fa_name') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .custom((value, {req}) => { + return Product.findOne({'product_details.fa.name': value}) + .then(product => { + if (product) return Promise.reject(v_m['fa'].duplicated.name) + else return true + }) + }), - body('en_name') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .custom((value, {req}) => { - return Product.findOne({'product_details.en.name': value}) - .then(product => { - if (product) return Promise.reject(v_m['fa'].duplicated.name) - else return true - }) - }), + body('en_name') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .custom((value, {req}) => { + return Product.findOne({'product_details.en.name': value}) + .then(product => { + if (product) return Promise.reject(v_m['fa'].duplicated.name) + else return true + }) + }), - body('fa_short_description') - .notEmpty().withMessage(v_m['fa'].required.caption) - .bail() - .isLength({max: 100}).withMessage(v_m['fa'].max_char.max100), + body('fa_short_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('en_short_description') - .notEmpty().withMessage(v_m['fa'].required.caption) - .bail() - .isLength({max: 100}).withMessage(v_m['fa'].max_char.max100), + body('en_short_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('fa_page_title') - .notEmpty().withMessage(v_m['fa'].required.title), + body('fa_page_title') + .notEmpty().withMessage(v_m['fa'].required.title), - body('en_page_title') - .notEmpty().withMessage(v_m['fa'].required.title), + body('en_page_title') + .notEmpty().withMessage(v_m['fa'].required.title), - body('fa_page_description') - .notEmpty().withMessage(v_m['fa'].required.caption), + body('fa_page_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('en_page_description') - .notEmpty().withMessage(v_m['fa'].required.caption), + body('en_page_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('en_page_description') - .notEmpty().withMessage(v_m['fa'].required.caption), + body('en_page_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('category') - .notEmpty().withMessage(v_m['fa'].required.category) - ], - async (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - if (!req.files || !req.files.cover) return res.status(422).json({validation: {cover: {msg: v_m['fa'].required.cover}}}) + body('category') + .notEmpty().withMessage(v_m['fa'].required.category) + ], + async (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + if (!req.files || !req.files.cover) return res.status(422).json({validation: {cover: {msg: v_m['fa'].required.cover}}}) - let cover = 'product_' + Date.now() + '.' + req.files.cover.mimetype.split('/')[1] - let more_section_image1 = null - let more_section_image2 = null - let render_image1 = null - let render_image2 = null - let chart_image = null + let cover = 'product_' + Date.now() + '.' + req.files.cover.mimetype.split('/')[1] + let thumb = 'thumb_' + cover + let more_section_image1 = null + let more_section_image2 = null + let render_image1 = null + let render_image2 = null + let chart_image = null - //// generate files names - if (req.files) { - if (req.files.more_section_image1) { - more_section_image1 = 'product_' + Date.now() + 1 + '.' + req.files.more_section_image1.mimetype.split('/')[1] - } - if (req.files.more_section_image2) { - more_section_image2 = 'product_' + Date.now() + 2 + '.' + req.files.more_section_image2.mimetype.split('/')[1] - } - if (req.files.render_image1) { - render_image1 = 'product_' + Date.now() + 3 + '.' + req.files.render_image1.mimetype.split('/')[1] - } - if (req.files.render_image2) { - render_image2 = 'product_' + Date.now() + 4 + '.' + req.files.render_image2.mimetype.split('/')[1] - } - if (req.files.chart_image) { - chart_image = 'product_' + Date.now() + 5 + '.' + req.files.chart_image.mimetype.split('/')[1] - } + //// generate files names + if (req.files) { + if (req.files.more_section_image1) { + more_section_image1 = 'product_' + Date.now() + 1 + '.' + req.files.more_section_image1.mimetype.split('/')[1] } - - - const data = { - cover: cover, - category: req.body.category, - more_section: req.body.more_section, - download_section: req.body.download_section, - product_details: { - fa: { - name: req.body.fa_name, - short_description: req.body.fa_short_description, - page_title: req.body.fa_page_title, - page_description: req.body.fa_page_description, - more_title1: req.body.fa_more_title1, - more_description1: req.body.fa_more_description1, - more_title2: req.body.fa_more_title2, - more_description2: req.body.fa_more_description2, - render_caption1: req.body.fa_render_caption1, - render_caption2: req.body.fa_render_caption2, - chart_title: req.body.fa_chart_title, - chart_description: req.body.fa_chart_description - }, - en: { - name: req.body.en_name, - short_description: req.body.en_short_description, - page_title: req.body.en_page_title, - page_description: req.body.en_page_description, - more_title1: req.body.en_more_title1, - more_description1: req.body.en_more_description1, - more_title2: req.body.en_more_title2, - more_description2: req.body.en_more_description2, - render_caption1: req.body.en_render_caption1, - render_caption2: req.body.en_render_caption2, - chart_title: req.body.en_chart_title, - chart_description: req.body.en_chart_description - } - }, - created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + if (req.files.more_section_image2) { + more_section_image2 = 'product_' + Date.now() + 2 + '.' + req.files.more_section_image2.mimetype.split('/')[1] } - if (req.files.more_section_image1) data.more_section_image1 = more_section_image1 - if (req.files.more_section_image2) data.more_section_image2 = more_section_image2 - if (req.files.render_image1) data.render_image1 = render_image1 - if (req.files.render_image2) data.render_image2 = render_image2 - if (req.files.chart_image) data.chart_image = chart_image - - //// save images - if (req.files) { - if (req.files.cover) { - await jimp.read(req.files.cover.data) - .then(img => { - img - .resize(470, jimp.AUTO) - .cover(470, 390) - .quality(70) - .write(`./static/uploads/images/products/${cover}`) - }) - } - if (req.files.more_section_image1) { - await jimp.read(req.files.more_section_image1.data) - .then(img => { - img - .resize(778, jimp.AUTO) - .cover(778, 395) - .quality(70) - .write(`./static/uploads/images/products/${more_section_image1}`) - }) - } - if (req.files.more_section_image2) { - await jimp.read(req.files.more_section_image2.data) - .then(img => { - img - .resize(778, jimp.AUTO) - .cover(778, 395) - .quality(70) - .write(`./static/uploads/images/products/${more_section_image2}`) - }) - } - if (req.files.render_image1) { - await jimp.read(req.files.render_image1.data) - .then(img => { - img - .resize(300, jimp.AUTO) - .cover(300, 300) - .quality(70) - .write(`./static/uploads/images/products/${render_image1}`) - }) - } - if (req.files.render_image2) { - await jimp.read(req.files.render_image2.data) - .then(img => { - img - .resize(300, jimp.AUTO) - .cover(300, 300) - .quality(70) - .write(`./static/uploads/images/products/${render_image2}`) - }) - } - if (req.files.chart_image) { - await jimp.read(req.files.chart_image.data) - .then(img => { - img - .quality(100) - .write(`./static/uploads/images/products/${chart_image}`) - }) - } + if (req.files.render_image1) { + render_image1 = 'product_' + Date.now() + 3 + '.' + req.files.render_image1.mimetype.split('/')[1] } + if (req.files.render_image2) { + render_image2 = 'product_' + Date.now() + 4 + '.' + req.files.render_image2.mimetype.split('/')[1] + } + if (req.files.chart_image) { + chart_image = 'product_' + Date.now() + 5 + '.' + req.files.chart_image.mimetype.split('/')[1] + } + } - //// write to database - const product = new Product(data) - product.save((err, data) => { - if (err) console.log(err) - return res.json(data) - }) - } + + const data = { + cover: cover, + thumb: thumb, + category: req.body.category, + more_section: req.body.more_section, + download_section: req.body.download_section, + favorite: req.body.favorite, + product_details: { + fa: { + name: req.body.fa_name, + short_description: req.body.fa_short_description.slice(0, shortDescriptionLength) + ' ... ', + page_title: req.body.fa_page_title, + page_description: req.body.fa_page_description, + more_title1: req.body.fa_more_title1, + more_description1: req.body.fa_more_description1, + more_title2: req.body.fa_more_title2, + more_description2: req.body.fa_more_description2, + render_caption1: req.body.fa_render_caption1, + render_caption2: req.body.fa_render_caption2, + chart_title: req.body.fa_chart_title, + chart_description: req.body.fa_chart_description + }, + en: { + name: req.body.en_name, + short_description: req.body.en_short_description.slice(0, shortDescriptionLength) + ' ... ', + page_title: req.body.en_page_title, + page_description: req.body.en_page_description, + more_title1: req.body.en_more_title1, + more_description1: req.body.en_more_description1, + more_title2: req.body.en_more_title2, + more_description2: req.body.en_more_description2, + render_caption1: req.body.en_render_caption1, + render_caption2: req.body.en_render_caption2, + chart_title: req.body.en_chart_title, + chart_description: req.body.en_chart_description + } + }, + created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + } + if (req.files.more_section_image1) data.more_section_image1 = more_section_image1 + if (req.files.more_section_image2) data.more_section_image2 = more_section_image2 + if (req.files.render_image1) data.render_image1 = render_image1 + if (req.files.render_image2) data.render_image2 = render_image2 + if (req.files.chart_image) data.chart_image = chart_image + + //// save images + if (req.files) { + if (req.files.cover) { + await jimp.read(req.files.cover.data) + .then(img => { + img + .cover(coverWidth, coverHeight) + .quality(coverQuality) + .write(`./static/uploads/images/products/${cover}`) + .resize(thumbWidth, jimp.AUTO) + .cover(thumbWidth, thumbHeight) + .quality(thumbQuality) + .write(`./static/uploads/images/products/${thumb}`) + }) + } + if (req.files.more_section_image1) { + await jimp.read(req.files.more_section_image1.data) + .then(img => { + img + .resize(moreSectionWidth, jimp.AUTO) + .cover(moreSectionWidth, moreSectionHeight) + .quality(moreSectionQuality) + .write(`./static/uploads/images/products/${more_section_image1}`) + }) + } + if (req.files.more_section_image2) { + await jimp.read(req.files.more_section_image2.data) + .then(img => { + img + .resize(moreSectionWidth, jimp.AUTO) + .cover(moreSectionWidth, moreSectionHeight) + .quality(moreSectionQuality) + .write(`./static/uploads/images/products/${more_section_image2}`) + }) + } + if (req.files.render_image1) { + await jimp.read(req.files.render_image1.data) + .then(img => { + img + .resize(renderImageWidth, jimp.AUTO) + .cover(renderImageWidth, renderImageHeight) + .quality(renderImageQuality) + .write(`./static/uploads/images/products/${render_image1}`) + }) + } + if (req.files.render_image2) { + await jimp.read(req.files.render_image2.data) + .then(img => { + img + .resize(renderImageWidth, jimp.AUTO) + .cover(renderImageWidth, renderImageHeight) + .quality(renderImageQuality) + .write(`./static/uploads/images/products/${render_image2}`) + }) + } + if (req.files.chart_image) { + await jimp.read(req.files.chart_image.data) + .then(img => { + img + .quality(chartImageQuality) + .write(`./static/uploads/images/products/${chart_image}`) + }) + } + } + + //// write to database + const product = new Product(data) + product.save((err, data) => { + if (err) console.log(err) + return res.json(data) + }) + } ] -module.exports.getAllProductsByCategory = [ - (req, res) => { - Product.find({category: req.params.category}) - .select('-product_features -product_images -created_at -updated_at') - .exec((err, products) => { - if (err) console.log(err) - return res.json(products) - }) - } +module.exports.getFavoriteProducts = [ + (req, res) => { + Product.find({favorite: true}) + .select('thumb category product_details') + .exec((err, products) => { + if (err) console.log(err) + return res.json(products) + }) + } ] module.exports.getAllProducts = [ - (req, res) => { - Product.find({}).select('cover category product_details').exec((err, products) => { - if (err) console.log(err) - return res.json(products) - }) - } + (req, res) => { + Product.find({}).select('thumb category product_details favorite').exec((err, products) => { + if (err) console.log(err) + return res.json(products) + }) + } ] module.exports.getOneProduct = [ - async (req, res) => { - await Product.findById(req.params.id, async (err, product) => { - if (err) return res.status(404).json({message: err}) - return res.json(product) - }) - } + async (req, res) => { + await Product.findById(req.params.id, async (err, product) => { + if (err) return res.status(404).json({message: err}) + return res.json(product) + }) + } ] module.exports.updateProduct = [ - [ - body('fa_name') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .custom((value, {req}) => { - return Product.findOne({'product_details.fa.name': value}) - .then(product => { - if (product && product._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name) - else return true - }) - }), + [ + body('fa_name') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .custom((value, {req}) => { + return Product.findOne({'product_details.fa.name': value}) + .then(product => { + if (product && product._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name) + else return true + }) + }), - body('en_name') - .notEmpty().withMessage(v_m['fa'].required.title) - .bail() - .custom((value, {req}) => { - return Product.findOne({'product_details.en.name': value}) - .then(product => { - if (product && product._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name) - else return true - }) - }), + body('en_name') + .notEmpty().withMessage(v_m['fa'].required.title) + .bail() + .custom((value, {req}) => { + return Product.findOne({'product_details.en.name': value}) + .then(product => { + if (product && product._id.toString() !== req.params.id) return Promise.reject(v_m['fa'].duplicated.name) + else return true + }) + }), - body('fa_short_description') - .notEmpty().withMessage(v_m['fa'].required.caption) - .bail() - .isLength({max: 100}).withMessage(v_m['fa'].max_char.max100), + body('fa_short_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('en_short_description') - .notEmpty().withMessage(v_m['fa'].required.caption) - .bail() - .isLength({max: 100}).withMessage(v_m['fa'].max_char.max100), + body('en_short_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('fa_page_title') - .notEmpty().withMessage(v_m['fa'].required.title), + body('fa_page_title') + .notEmpty().withMessage(v_m['fa'].required.title), - body('en_page_title') - .notEmpty().withMessage(v_m['fa'].required.title), + body('en_page_title') + .notEmpty().withMessage(v_m['fa'].required.title), - body('fa_page_description') - .notEmpty().withMessage(v_m['fa'].required.caption), + body('fa_page_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('en_page_description') - .notEmpty().withMessage(v_m['fa'].required.caption), + body('en_page_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('en_page_description') - .notEmpty().withMessage(v_m['fa'].required.caption), + body('en_page_description') + .notEmpty().withMessage(v_m['fa'].required.caption), - body('category') - .notEmpty().withMessage(v_m['fa'].required.category) - ], - async (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + body('category') + .notEmpty().withMessage(v_m['fa'].required.category) + ], + async (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - let cover = null - let more_section_image1 = null - let more_section_image2 = null - let render_image1 = null - let render_image2 = null - let chart_image = null + let cover = null + let more_section_image1 = null + let more_section_image2 = null + let render_image1 = null + let render_image2 = null + let chart_image = null - //// generate files names + //// generate files names + if (req.files) { + if (req.files.cover) { + cover = 'product_' + Date.now() + '.' + req.files.cover.mimetype.split('/')[1] + thumb = 'thumb_' + cover + } + if (req.files.more_section_image1) { + more_section_image1 = 'product_' + Date.now() + 1 + '.' + req.files.more_section_image1.mimetype.split('/')[1] + } + if (req.files.more_section_image2) { + more_section_image2 = 'product_' + Date.now() + 2 + '.' + req.files.more_section_image2.mimetype.split('/')[1] + } + if (req.files.render_image1) { + render_image1 = 'product_' + Date.now() + 3 + '.' + req.files.render_image1.mimetype.split('/')[1] + } + if (req.files.render_image2) { + render_image2 = 'product_' + Date.now() + 4 + '.' + req.files.render_image2.mimetype.split('/')[1] + } + if (req.files.chart_image) { + chart_image = 'product_' + Date.now() + 5 + '.' + req.files.chart_image.mimetype.split('/')[1] + } + } + + + const data = { + category: req.body.category, + more_section: req.body.more_section, + download_section: req.body.download_section, + favorite: req.body.favorite, + product_details: { + fa: { + name: req.body.fa_name, + short_description: req.body.fa_short_description.slice(0, shortDescriptionLength) + ' ... ', + page_title: req.body.fa_page_title, + page_description: req.body.fa_page_description, + more_title1: req.body.fa_more_title1, + more_description1: req.body.fa_more_description1, + more_title2: req.body.fa_more_title2, + more_description2: req.body.fa_more_description2, + render_caption1: req.body.fa_render_caption1, + render_caption2: req.body.fa_render_caption2, + chart_title: req.body.fa_chart_title, + chart_description: req.body.fa_chart_description + }, + en: { + name: req.body.en_name, + short_description: req.body.en_short_description.slice(0, shortDescriptionLength) + ' ... ', + page_title: req.body.en_page_title, + page_description: req.body.en_page_description, + more_title1: req.body.en_more_title1, + more_description1: req.body.en_more_description1, + more_title2: req.body.en_more_title2, + more_description2: req.body.en_more_description2, + render_caption1: req.body.en_render_caption1, + render_caption2: req.body.en_render_caption2, + chart_title: req.body.en_chart_title, + chart_description: req.body.en_chart_description + } + }, + updated_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + } + + //// save images + if (req.files) { + if (req.files.cover) { + data.cover = cover + data.thumb = thumb + await jimp.read(req.files.cover.data) + .then(img => { + img + .cover(coverWidth, coverHeight) + .quality(coverQuality) + .write(`./static/uploads/images/products/${cover}`) + .resize(thumbWidth, jimp.AUTO) + .cover(thumbWidth, thumbHeight) + .quality(thumbQuality) + .write(`./static/uploads/images/products/${thumb}`) + }) + } + + if (req.files.more_section_image1) { + data.more_section_image1 = more_section_image1 + await jimp.read(req.files.more_section_image1.data) + .then(img => { + img + .resize(moreSectionWidth, jimp.AUTO) + .cover(moreSectionWidth, moreSectionHeight) + .quality(moreSectionQuality) + .write(`./static/uploads/images/products/${more_section_image1}`) + }) + } + + if (req.files.more_section_image2) { + data.more_section_image2 = more_section_image2 + await jimp.read(req.files.more_section_image2.data) + .then(img => { + img + .resize(moreSectionWidth, jimp.AUTO) + .cover(moreSectionWidth, moreSectionHeight) + .quality(moreSectionQuality) + .write(`./static/uploads/images/products/${more_section_image2}`) + }) + } + + if (req.files.render_image1) { + data.render_image1 = render_image1 + await jimp.read(req.files.render_image1.data) + .then(img => { + img + .resize(renderImageWidth, jimp.AUTO) + .cover(renderImageWidth, renderImageHeight) + .quality(renderImageQuality) + .write(`./static/uploads/images/products/${render_image1}`) + }) + } + + if (req.files.render_image2) { + data.render_image2 = render_image2 + await jimp.read(req.files.render_image2.data) + .then(img => { + img + .resize(renderImageWidth, jimp.AUTO) + .cover(renderImageWidth, renderImageHeight) + .quality(renderImageQuality) + .write(`./static/uploads/images/products/${render_image2}`) + }) + } + + if (req.files.chart_image) { + data.chart_image = chart_image + await jimp.read(req.files.chart_image.data) + .then(img => { + img + .quality(chartImageQuality) + .write(`./static/uploads/images/products/${chart_image}`) + }) + } + } + + //// write to database + Product.findByIdAndUpdate(req.params.id, data, (err, oldData) => { + if (err) console.log(err) if (req.files) { - if (req.files.cover) { - cover = 'product_' + Date.now() + '.' + req.files.cover.mimetype.split('/')[1] - } - if (req.files.more_section_image1) { - more_section_image1 = 'product_' + Date.now() + 1 + '.' + req.files.more_section_image1.mimetype.split('/')[1] - } - if (req.files.more_section_image2) { - more_section_image2 = 'product_' + Date.now() + 2 + '.' + req.files.more_section_image2.mimetype.split('/')[1] - } - if (req.files.render_image1) { - render_image1 = 'product_' + Date.now() + 3 + '.' + req.files.render_image1.mimetype.split('/')[1] - } - if (req.files.render_image2) { - render_image2 = 'product_' + Date.now() + 4 + '.' + req.files.render_image2.mimetype.split('/')[1] - } - if (req.files.chart_image) { - chart_image = 'product_' + Date.now() + 5 + '.' + req.files.chart_image.mimetype.split('/')[1] - } - } - - - const data = { - category: req.body.category, - more_section: req.body.more_section, - download_section: req.body.download_section, - product_details: { - fa: { - name: req.body.fa_name, - short_description: req.body.fa_short_description, - page_title: req.body.fa_page_title, - page_description: req.body.fa_page_description, - more_title1: req.body.fa_more_title1, - more_description1: req.body.fa_more_description1, - more_title2: req.body.fa_more_title2, - more_description2: req.body.fa_more_description2, - render_caption1: req.body.fa_render_caption1, - render_caption2: req.body.fa_render_caption2, - chart_title: req.body.fa_chart_title, - chart_description: req.body.fa_chart_description - }, - en: { - name: req.body.en_name, - short_description: req.body.en_short_description, - page_title: req.body.en_page_title, - page_description: req.body.en_page_description, - more_title1: req.body.en_more_title1, - more_description1: req.body.en_more_description1, - more_title2: req.body.en_more_title2, - more_description2: req.body.en_more_description2, - render_caption1: req.body.en_render_caption1, - render_caption2: req.body.en_render_caption2, - chart_title: req.body.en_chart_title, - chart_description: req.body.en_chart_description - } - }, - created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') - } - - if (req.files) { - if (req.files.cover) data.cover = cover - if (req.files.more_section_image1) data.more_section_image1 = more_section_image1 - if (req.files.more_section_image2) data.more_section_image2 = more_section_image2 - if (req.files.render_image1) data.render_image1 = render_image1 - if (req.files.render_image2) data.render_image2 = render_image2 - if (req.files.chart_image) data.chart_image = chart_image - } - - //// save images - if (req.files) { - if (req.files.cover) { - await jimp.read(req.files.cover.data) - .then(img => { - img - .resize(470, jimp.AUTO) - .cover(470, 390) - .quality(70) - .write(`./static/uploads/images/products/${cover}`) - }) - } - if (req.files.more_section_image1) { - await jimp.read(req.files.more_section_image1.data) - .then(img => { - img - .resize(778, jimp.AUTO) - .cover(778, 395) - .quality(70) - .write(`./static/uploads/images/products/${more_section_image1}`) - }) - } - if (req.files.more_section_image2) { - await jimp.read(req.files.more_section_image2.data) - .then(img => { - img - .resize(778, jimp.AUTO) - .cover(778, 395) - .quality(70) - .write(`./static/uploads/images/products/${more_section_image2}`) - }) - } - if (req.files.render_image1) { - await jimp.read(req.files.render_image1.data) - .then(img => { - img - .resize(300, jimp.AUTO) - .cover(300, 300) - .quality(70) - .write(`./static/uploads/images/products/${render_image1}`) - }) - } - if (req.files.render_image2) { - await jimp.read(req.files.render_image2.data) - .then(img => { - img - .resize(300, jimp.AUTO) - .cover(300, 300) - .quality(70) - .write(`./static/uploads/images/products/${render_image2}`) - }) - } - if (req.files.chart_image) { - await jimp.read(req.files.chart_image.data) - .then(img => { - img - .quality(100) - .write(`./static/uploads/images/products/${chart_image}`) - }) - } - } - - //// write to database - Product.findByIdAndUpdate(req.params.id, data, (err, oldData) => { - if (err) console.log(err) - if (req.files) { - if (req.files.cover) fs.unlink(`./static/${oldData.cover}`, err => { - if (err) console.log(err) - }) - if (req.files.more_section_image1 && oldData.more_section_image1) fs.unlink(`./static/${oldData.more_section_image1}`, err => { - if (err) console.log(err) - }) - if (req.files.more_section_image2 && oldData.more_section_image2) fs.unlink(`./static/${oldData.more_section_image2}`, err => { - if (err) console.log(err) - }) - if (req.files.render_image1 && oldData.render_image1) fs.unlink(`./static/${oldData.render_image1}`, err => { - if (err) console.log(err) - }) - if (req.files.render_image2 && oldData.render_image2) fs.unlink(`./static/${oldData.render_image2}`, err => { - if (err) console.log(err) - }) - if (req.files.chart_image && oldData.chart_image) fs.unlink(`./static/${oldData.chart_image}`, err => { - if (err) console.log(err) - }) - } - Product.findById(oldData._id, (err, data) => { + if (req.files.cover) { + fs.unlink(`./static/${oldData.cover}`, err => { if (err) console.log(err) - return res.json(data) - }) + }) + fs.unlink(`./static/${oldData.thumb}`, err => { + if (err) console.log(err) + }) + } + if (req.files.more_section_image1 && oldData.more_section_image1) fs.unlink(`./static/${oldData.more_section_image1}`, err => { + if (err) console.log(err) + }) + if (req.files.more_section_image2 && oldData.more_section_image2) fs.unlink(`./static/${oldData.more_section_image2}`, err => { + if (err) console.log(err) + }) + if (req.files.render_image1 && oldData.render_image1) fs.unlink(`./static/${oldData.render_image1}`, err => { + if (err) console.log(err) + }) + if (req.files.render_image2 && oldData.render_image2) fs.unlink(`./static/${oldData.render_image2}`, err => { + if (err) console.log(err) + }) + if (req.files.chart_image && oldData.chart_image) fs.unlink(`./static/${oldData.chart_image}`, err => { + if (err) console.log(err) + }) + } + Product.findById(oldData._id, (err, data) => { + if (err) console.log(err) + return res.json(data) }) - } + }) + } ] module.exports.deleteProduct = [ - (req, res) => { - Product.findByIdAndDelete(req.params.id, (err, product) => { - if (err) console.log(err) - return res.json({message: v_m['fa'].response.success_remove}) + (req, res) => { + Product.findByIdAndDelete(req.params.id, (err, product) => { + if (err) console.log(err) + + fs.unlink(`./static/${product.cover}`, err => { + if (err) console.log(err) }) - } + fs.unlink(`./static/${product.thumb}`, err => { + if (err) console.log(err) + }) + + if (product.more_section_image1) fs.unlink(`./static/${product.more_section_image1}`, err => { + if (err) console.log(err) + }) + if (product.more_section_image2) fs.unlink(`./static/${product.more_section_image2}`, err => { + if (err) console.log(err) + }) + if (product.render_image1) fs.unlink(`./static/${product.render_image1}`, err => { + if (err) console.log(err) + }) + if (product.render_image2) fs.unlink(`./static/${product.render_image2}`, err => { + if (err) console.log(err) + }) + if (product.chart_image) fs.unlink(`./static/${product.chart_image}`, err => { + if (err) console.log(err) + }) + + if (product.images.length) { + product.images.forEach(item => { + fs.unlink(`./static/${item.image}`, err => { + if (err) console.log(err) + }) + }) + } + + if (product.pdf_files.length) { + product.pdf_files.forEach(item => { + fs.unlink(`./static/${item.file.fa}`, err => { + if (err) console.log(err) + }) + fs.unlink(`./static/${item.file.en}`, err => { + if (err) console.log(err) + }) + }) + } + return res.json({message: v_m['fa'].response.success_remove}) + }) + } ] ////////////////////////////////////////// products images controllers module.exports.createProductImage = [ - [ - body('product_id') - .custom((value, {req}) => { - return Product.findById(value) - .then(product => { - return true - }) - .catch(err => { - return Promise.reject(v_m['fa'].not_found.item_id) - }) - }) - ], - (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: {images: errors.mapped()}}) - - let image - let imageName - if (req.files && req.files.image) { - image = req.files.image - imageName = 'productImages_' + Date.now() + '.' + image.mimetype.split('/')[1] - - jimp.read(image.data) - .then(img => { - img - .resize(470, jimp.AUTO) - .cover(470, 390) - .write(`./static/uploads/images/products/${imageName}`) - - //// write to database - Product.findById(req.body.product_id, (err, product) => { - if (err) console.log(err) - product.images.push({ - image: imageName, - created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') - }) - product.save() - return res.json(product) - }) + [ + body('product_id') + .custom((value, {req}) => { + return Product.findById(value) + .then(product => { + return true }) + .catch(err => { + return Promise.reject(v_m['fa'].not_found.item_id) + }) + }) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: {images: errors.mapped()}}) - } else { - return res.status(422).json({validation: {images: {image: {msg: v_m['fa'].required.image}}}}) - } - } + let image + let imageName + if (req.files && req.files.image) { + image = req.files.image + imageName = 'productImages_' + Date.now() + '.' + image.mimetype.split('/')[1] + + jimp.read(image.data) + .then(img => { + img + .cover(coverWidth, coverHeight) + .quality(coverQuality) + .write(`./static/uploads/images/products/${imageName}`) + + //// write to database + Product.findById(req.body.product_id, (err, product) => { + if (err) console.log(err) + product.images.push({ + image: imageName, + created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + }) + product.save() + return res.json(product) + }) + }) + + } else { + return res.status(422).json({validation: {images: {image: {msg: v_m['fa'].required.image}}}}) + } + } ] module.exports.deleteProductImage = [ - (req, res) => { - Product.findOne({'images._id': req.params.imageID}, (err, product) => { - if (err) return res.status(404).json(err) - const productImage = product.images.id(req.params.imageID) - fs.unlink(`./static/${productImage.image}`, err => { - if (err) console.log(err) - }) - productImage.remove() - product.save(err => { - if (err) console.log(err) - }) - return res.json(product) + (req, res) => { + Product.findOne({'images._id': req.params.imageID}, (err, product) => { + if (err) return res.status(404).json(err) + const productImage = product.images.id(req.params.imageID) + fs.unlink(`./static/${productImage.image}`, err => { + if (err) console.log(err) }) - } + productImage.remove() + product.save(err => { + if (err) console.log(err) + }) + return res.json(product) + }) + } ] ////////////////////////////////////////// products features controllers module.exports.createPDF = [ - [ - body('fa_pdf') - .notEmpty().withMessage(v_m['fa'].required.title), - body('en_pdf') - .notEmpty().withMessage(v_m['fa'].required.title), + [ + body('fa_pdf') + .notEmpty().withMessage(v_m['fa'].required.title), + body('en_pdf') + .notEmpty().withMessage(v_m['fa'].required.title), - body('product_id') - .custom((value, {req}) => { - return Product.findById(value) - .then(product => { - return true - }) - .catch(err => { - return Promise.reject(v_m['fa'].not_found.item_id) - }) - }) - ], - (req, res) => { - const errors = validationResult(req) - if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) - if (!req.files || !req.files.pdf) return res.status(422).json({validation: {pdf: {msg: v_m['fa'].required.file}}}) + body('product_id') + .custom((value, {req}) => { + return Product.findById(value) + .then(product => { + return true + }) + .catch(err => { + return Promise.reject(v_m['fa'].not_found.item_id) + }) + }) + ], + (req, res) => { + const errors = validationResult(req) + if (!errors.isEmpty()) return res.status(422).json({validation: errors.mapped()}) + if (!req.files || !req.files.file_fa) return res.status(422).json({validation: {file_fa: {msg: v_m['fa'].required.file}}}) + if (!req.files || !req.files.file_en) return res.status(422).json({validation: {file_en: {msg: v_m['fa'].required.file}}}) - let file = 'pdf_' + Date.now() + '.' + req.files.pdf.mimetype.split('/')[1] - req.files.pdf.mv(`./static/uploads/pdf/${file}`, err => { - if (err) console.log(err) + Product.findById(req.body.product_id, (err, product) => { + if (err) console.log(err) + + let fileFa = 'fa_' + product.product_details.fa.name + Date.now() + '.' + req.files.file_fa.mimetype.split('/')[1] + let fileEn = 'en_' + product.product_details.en.name + Date.now() + '.' + req.files.file_en.mimetype.split('/')[1] + req.files.file_fa.mv(`./static/uploads/pdf/${fileFa}`, err => { + if (err) console.log(err) + }) + req.files.file_en.mv(`./static/uploads/pdf/${fileEn}`, err => { + if (err) console.log(err) }) const data = { - file: file, - pdf_details: { - fa: { - name: req.body.fa_pdf - }, - en: { - name: req.body.en_pdf - } - }, - created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') + file: { + fa: fileFa, + en: fileEn + }, + pdf_details: { + fa: { + name: req.body.fa_pdf + }, + en: { + name: req.body.en_pdf + } + }, + created_at: dateformat(Date.now(), 'yyyy-mm-dd HH:MM:ss') } - Product.findById(req.body.product_id, (err, product) => { - if (err) console.log(err) - product.pdf_files.push(data) - product.save() - return res.json(product) - }) - } + product.pdf_files.push(data) + product.save() + return res.json(product) + }) + } ] module.exports.deletePDF = [ - (req, res) => { - Product.findOne({'pdf_files._id': req.params.pdfID}, (err, product) => { - if (err) return res.status(500).json({message: err}) - let pdf = product.pdf_files.id(req.params.pdfID) - pdf.remove(cb => { - fs.unlink(`./static/${pdf.file}`, err => { - if (err) console.log(err) - }) - }) - product.save() - return res.json(product) + (req, res) => { + Product.findOne({'pdf_files._id': req.params.pdfID}, (err, product) => { + if (err) return res.status(500).json({message: err}) + let pdf = product.pdf_files.id(req.params.pdfID) + pdf.remove(cb => { + fs.unlink(`./static/${pdf.file.fa}`, err => { + if (err) console.log(err) + }) + fs.unlink(`./static/${pdf.file.en}`, err => { + if (err) console.log(err) + }) }) - } + product.save() + return res.json(product) + }) + } ] diff --git a/api/models/MainCatalog.js b/api/models/MainCatalog.js index 8064658..a62251c 100644 --- a/api/models/MainCatalog.js +++ b/api/models/MainCatalog.js @@ -1,15 +1,19 @@ const mongoose = require('mongoose') function catalog(pdf) { - return '/uploads/pdf/' + pdf + if (pdf) return '/uploads/pdf/' + pdf } const MainCatalogSchema = mongoose.Schema({ - file: {type: String, get: catalog}, - created_at: String + file: { + fa: {type: String, get: catalog}, + en: {type: String, get: catalog} + }, + created_at: String, + updated_at: String }, { - toObject: {getters: true}, - toJSON: {getters: true} + toObject: {getters: true}, + toJSON: {getters: true} }) module.exports = mongoose.model('MainCatalog', MainCatalogSchema) diff --git a/api/models/product/Product.js b/api/models/product/Product.js index 1d317d0..6906c90 100644 --- a/api/models/product/Product.js +++ b/api/models/product/Product.js @@ -1,84 +1,89 @@ const mongoose = require('mongoose') function productImage(img) { - return '/uploads/images/products/' + img + if (img) return '/uploads/images/products/' + img } function productPDF(file) { - return '/uploads/pdf/' + file + if (file) return '/uploads/pdf/' + file } const ProductImageSchema = mongoose.Schema({ - image: {type: String, get: productImage}, - created_at: String + image: {type: String, get: productImage}, + created_at: String }, { - toObject: {getters: true}, - toJSON: {getters: true} + toObject: {getters: true}, + toJSON: {getters: true} }) const ProductPDFSchema = mongoose.Schema({ - file: {type: String, get: productPDF}, - pdf_details: { - fa: { - name: String - }, - en: { - name: String - } - }, - created_at: String + file: { + fa: {type: String, get: productPDF}, + en: {type: String, get: productPDF} + }, + pdf_details: { + fa: { + name: String + }, + en: { + name: String + } + }, + created_at: String }, { - toObject: {getters: true}, - toJSON: {getters: true} + toObject: {getters: true}, + toJSON: {getters: true} }) const ProductSchema = mongoose.Schema({ - cover: {type: String, get: productImage}, - images: [ProductImageSchema], - more_section_image1: {type: String, get: productImage}, - more_section_image2: {type: String, get: productImage}, - render_image1: {type: String, get: productImage}, - render_image2: {type: String, get: productImage}, - chart_image: {type: String, get: productImage}, - pdf_files: [ProductPDFSchema], - category: String, - more_section: {type: Boolean, default: true}, - download_section: {type: Boolean, default: true}, - product_details: { - fa: { - name: String, - short_description: String, - page_title: String, - page_description: String, - more_title1: String, - more_description1: String, - more_title2: String, - more_description2: String, - render_caption1: String, - render_caption2: String, - chart_title: String, - chart_description: String - }, - en: { - name: String, - short_description: String, - page_title: String, - page_description: String, - more_title1: String, - more_description1: String, - more_title2: String, - more_description2: String, - render_caption1: String, - render_caption2: String, - chart_title: String, - chart_description: String - } - }, - created_at: String, - updated_at: String + cover: {type: String, get: productImage}, + thumb: {type: String, get: productImage}, + images: [ProductImageSchema], + more_section_image1: {type: String, get: productImage}, + more_section_image2: {type: String, get: productImage}, + render_image1: {type: String, get: productImage}, + render_image2: {type: String, get: productImage}, + chart_image: {type: String, get: productImage}, + pdf_files: [ProductPDFSchema], + category: String, + more_section: {type: Boolean, default: true}, + download_section: {type: Boolean, default: true}, + favorite: {type: Boolean, default: false}, + product_details: { + fa: { + name: String, + short_description: String, + page_title: String, + page_description: String, + more_title1: String, + more_description1: String, + more_title2: String, + more_description2: String, + render_caption1: String, + render_caption2: String, + chart_title: String, + chart_description: String + }, + en: { + name: String, + short_description: String, + page_title: String, + page_description: String, + more_title1: String, + more_description1: String, + more_title2: String, + more_description2: String, + render_caption1: String, + render_caption2: String, + chart_title: String, + chart_description: String + } + }, + created_at: String, + updated_at: String }, { - toObject: {getters: true}, - toJSON: {getters: true} + toObject: {getters: true}, + toJSON: {getters: true} }) diff --git a/api/routes/public.js b/api/routes/public.js index 1ed7fa4..2fe2577 100644 --- a/api/routes/public.js +++ b/api/routes/public.js @@ -12,6 +12,7 @@ const contactPageController = require('../controllers/contactPageController') const contactUsReasonController = require('../controllers/contactUsReasonController') const mainCatalogController = require('../controllers/mainCatalogController') const historyController = require('../controllers/historyController') +const calculationModule = require('../controllers/calculationModule') /////////////////////////////////////////////////////////// routes //////////////// slider @@ -31,7 +32,7 @@ router.get('/productCategories', productCategoryController.getAll) router.get('/productCategories/:id', productCategoryController.getOne) //////////////// products -router.get('/products/:category', productController.getAllProductsByCategory) +router.get('/favoriteProducts', productController.getFavoriteProducts) router.get('/products/', productController.getAllProducts) router.get('/product/:id', productController.getOneProduct) @@ -51,4 +52,9 @@ router.get('/catalog', mainCatalogController.get) router.get('/history', historyController.getAll) router.get('/history/:id', historyController.getOne) +//////////////// calculation +router.get('/calculation/values', calculationModule.getValues) +router.post('/calculation/relativeValues', calculationModule.getRelativeValues) +router.post('/calculate', calculationModule.calculate) + module.exports = router diff --git a/assets/admin/sass/admin.scss b/assets/admin/sass/admin.scss index d359329..c7086f1 100644 --- a/assets/admin/sass/admin.scss +++ b/assets/admin/sass/admin.scss @@ -127,7 +127,7 @@ $panelBg: #fff; padding: 0 15px; position: fixed; top: 56px; - left: 15px; + left: 0; z-index: 5; h2 { @@ -177,10 +177,11 @@ $panelBg: #fff; } .admin--sidebar { - min-height: calc(100vh - 55px); + height: calc(100vh - 55px); background: $sidebar; flex-basis: 300px; border-left: 1px solid $borders; + overflow: auto; ul { width: 100%; @@ -231,6 +232,23 @@ $panelBg: #fff; .admin-user { padding: 20px 15px; color: $usernameColor; + display: flex; + flex-direction: row; + justify-content: flex-start; + align-items: center; + flex-wrap: nowrap; + + .el-avatar { + display: block; + width: 50px; + height: 50px; + + img { + width: 100%; + height: 100%; + object-fit: cover; + } + } h2 { font-size: 25px !important; @@ -254,6 +272,11 @@ $panelBg: #fff; } } } + + .sidebar--content { + height: 100%; + overflow: auto; + } } .admin--header { @@ -320,6 +343,11 @@ $panelBg: #fff; text-align: center; } + .err { + color: red; + font-size: 13px; + } + } pre { @@ -382,11 +410,6 @@ html:lang(fa) { margin-top: 50px; } - .err { - color: red; - font-size: 13px; - } - .el-upload__input { display: none !important; } diff --git a/assets/fonts/sahel/Sahel-Bold-FD.eot b/assets/fonts/sahel/Sahel-Bold-FD.eot deleted file mode 100644 index bcac950..0000000 Binary files a/assets/fonts/sahel/Sahel-Bold-FD.eot and /dev/null differ diff --git a/assets/fonts/sahel/Sahel-Bold-FD.ttf b/assets/fonts/sahel/Sahel-Bold-FD.ttf deleted file mode 100644 index 62dc3eb..0000000 Binary files a/assets/fonts/sahel/Sahel-Bold-FD.ttf and /dev/null differ diff --git a/assets/fonts/sahel/Sahel-Bold-FD.woff b/assets/fonts/sahel/Sahel-Bold-FD.woff deleted file mode 100644 index 498712b..0000000 Binary files a/assets/fonts/sahel/Sahel-Bold-FD.woff and /dev/null differ diff --git a/assets/fonts/sahelWithLatin/black/Sahel-Black.eot b/assets/fonts/sahelWithLatin/black/Sahel-Black.eot new file mode 100644 index 0000000..7d4e00a Binary files /dev/null and b/assets/fonts/sahelWithLatin/black/Sahel-Black.eot differ diff --git a/assets/fonts/sahelWithLatin/black/Sahel-Black.ttf b/assets/fonts/sahelWithLatin/black/Sahel-Black.ttf new file mode 100644 index 0000000..db08bcd Binary files /dev/null and b/assets/fonts/sahelWithLatin/black/Sahel-Black.ttf differ diff --git a/assets/fonts/sahelWithLatin/black/Sahel-Black.woff b/assets/fonts/sahelWithLatin/black/Sahel-Black.woff new file mode 100644 index 0000000..4601533 Binary files /dev/null and b/assets/fonts/sahelWithLatin/black/Sahel-Black.woff differ diff --git a/assets/fonts/sahelWithLatin/regular/Sahel.eot b/assets/fonts/sahelWithLatin/regular/Sahel.eot new file mode 100644 index 0000000..a025f76 Binary files /dev/null and b/assets/fonts/sahelWithLatin/regular/Sahel.eot differ diff --git a/assets/fonts/sahelWithLatin/regular/Sahel.ttf b/assets/fonts/sahelWithLatin/regular/Sahel.ttf new file mode 100644 index 0000000..1779286 Binary files /dev/null and b/assets/fonts/sahelWithLatin/regular/Sahel.ttf differ diff --git a/assets/fonts/sahelWithLatin/regular/Sahel.woff b/assets/fonts/sahelWithLatin/regular/Sahel.woff new file mode 100644 index 0000000..6cca34a Binary files /dev/null and b/assets/fonts/sahelWithLatin/regular/Sahel.woff differ diff --git a/assets/img/about/pal.jpg b/assets/img/about/pal.jpg new file mode 100644 index 0000000..8607831 Binary files /dev/null and b/assets/img/about/pal.jpg differ diff --git a/assets/img/calculation/en_classes-descripttion.jpg b/assets/img/calculation/en_classes-descripttion.jpg new file mode 100644 index 0000000..8aa9b24 Binary files /dev/null and b/assets/img/calculation/en_classes-descripttion.jpg differ diff --git a/assets/img/grating-usage/13.jpg b/assets/img/grating-usage/13.jpg new file mode 100644 index 0000000..45b6fd7 Binary files /dev/null and b/assets/img/grating-usage/13.jpg differ diff --git a/assets/img/grating-usage/4.jpg b/assets/img/grating-usage/4.jpg new file mode 100644 index 0000000..db7a524 Binary files /dev/null and b/assets/img/grating-usage/4.jpg differ diff --git a/assets/img/grating-usage/8.jpg b/assets/img/grating-usage/8.jpg new file mode 100644 index 0000000..c0b9ff5 Binary files /dev/null and b/assets/img/grating-usage/8.jpg differ diff --git a/assets/img/grating-usage/88-wood-1.jpg b/assets/img/grating-usage/88-wood-1.jpg new file mode 100644 index 0000000..e5ddc95 Binary files /dev/null and b/assets/img/grating-usage/88-wood-1.jpg differ diff --git a/assets/img/grating-usage/industri-2.jpg b/assets/img/grating-usage/industri-2.jpg new file mode 100644 index 0000000..8021062 Binary files /dev/null and b/assets/img/grating-usage/industri-2.jpg differ diff --git a/assets/img/grating-usage/infills-1b.jpg b/assets/img/grating-usage/infills-1b.jpg new file mode 100644 index 0000000..18cae54 Binary files /dev/null and b/assets/img/grating-usage/infills-1b.jpg differ diff --git a/assets/img/products/hero.jpg b/assets/img/products/hero.jpg new file mode 100644 index 0000000..0381d74 Binary files /dev/null and b/assets/img/products/hero.jpg differ diff --git a/assets/img/projects/hero.jpg b/assets/img/projects/hero.jpg index ee9df65..3b35c88 100644 Binary files a/assets/img/projects/hero.jpg and b/assets/img/projects/hero.jpg differ diff --git a/assets/img/about/about-hero.jpg b/assets/img/services/hero.jpg similarity index 100% rename from assets/img/about/about-hero.jpg rename to assets/img/services/hero.jpg diff --git a/assets/sass/_CKEditorStyle.scss b/assets/sass/_CKEditorStyle.scss new file mode 100644 index 0000000..81f38c7 --- /dev/null +++ b/assets/sass/_CKEditorStyle.scss @@ -0,0 +1,74 @@ +.ck-content { + width: 100%; + direction: rtl; + text-align: right; + + &:lang(en) { + direction: ltr; + text-align: left; + } + + a { + display: inline-block; + color: blue; + } + + p, a, span, b, ul, li, em, h1, h2, h3, h4, h5, h6, strong { + font-family: inherit, sans-serif; + direction: unset; + text-align: unset; + + &:lang(en) { + font-family: inherit; + direction: unset; + text-align: unset; + } + + &[dir="ltr"] { + direction: ltr; + text-align: left; + + p, a, span, b, ul, li, em, h1, h2, h3, h4, h5, h6, strong { + direction: ltr; + text-align: left; + } + } + + &[dir="rtl"] { + direction: rtl; + text-align: right; + + p, a, span, b, ul, li, em, h1, h2, h3, h4, h5, h6, strong { + direction: rtl; + text-align: right; + } + } + } + + p { + line-height: 1.6em; + } + + h1, h2, h3, h4, h5, h6 { + line-height: 1.3em; + } + + li { + margin-bottom: 15px; + line-height: 1.6em; + } + + ol { + list-style: decimal; + list-style-position: inside; + } + + ul { + list-style: disc; + list-style-position: inside; + } + + img { + max-width: 100%!important; + } +} diff --git a/assets/sass/_fonts.scss b/assets/sass/_fonts.scss index f6041a4..2cc699c 100644 --- a/assets/sass/_fonts.scss +++ b/assets/sass/_fonts.scss @@ -6,12 +6,6 @@ url("../fonts/sahel/Sahel-FD.woff") format('woff'); } -@font-face { - font-family: 'sahel-bold'; - src: url("../fonts/sahel/Sahel-Bold-FD.eot") format('embedded-opentype'), - url("../fonts/sahel/Sahel-Bold-FD.ttf") format('truetype'), - url("../fonts/sahel/Sahel-Bold-FD.woff") format('woff'); -} @font-face { font-family: 'sahel-black'; @@ -20,6 +14,22 @@ url("../fonts/sahel/Sahel-Black-FD.woff") format('woff'); } +////// sahel with latin +@font-face { + font-family: 'sahel-LD'; + src: url("../fonts/sahelWithLatin/regular/Sahel.eot") format('embedded-opentype'), + url("../fonts/sahelWithLatin/regular/Sahel.ttf") format('truetype'), + url("../fonts/sahelWithLatin/regular/Sahel.woff") format('woff'); +} + +@font-face { + font-family: 'sahel-black-LD'; + src: url("../fonts/sahelWithLatin/black/Sahel-Black.eot") format('embedded-opentype'), + url("../fonts/sahelWithLatin/black/Sahel-Black.ttf") format('truetype'), + url("../fonts/sahelWithLatin/black/Sahel-Black.woff") format('woff'); +} + + ////// diodrum @font-face { font-family: 'diodrum'; diff --git a/assets/sass/_globalStyles.scss b/assets/sass/_globalStyles.scss index c002103..8dbb9a3 100644 --- a/assets/sass/_globalStyles.scss +++ b/assets/sass/_globalStyles.scss @@ -11,8 +11,8 @@ body { } } -p, a, span, b { - font-family: 'sahel'; +p, a, span, b, label, strong, small, li { + font-family: 'sahel', 'diodrum', sans-serif; color: rgba(0, 0, 0, 0.7); line-height: 1.6em; @@ -67,6 +67,24 @@ section { padding: 0 0 100px; } +.latin-digits { + p, a, span, b, label, strong, small, li, td, tr, th { + font-family: 'sahel-LD', 'diodrum', sans-serif; + + &:lang(en) { + font-family: 'diodrum'; + } + } + + h1, h2, h3, h4, h5, h6 { + font-family: 'sahel-black-LD'; + + &:lang(en) { + font-family: 'diodrum-bold'; + } + } +} + @keyframes loading { 0% { @include transform(rotateZ(0)); @@ -168,6 +186,11 @@ section { display: flex; align-items: stretch; background: $darkGray; + direction: ltr; + + &:lang(en) { + direction: rtl; + } .catalog-download { display: block; diff --git a/assets/sass/_pages.scss b/assets/sass/_pages.scss index d5908e7..5c75c21 100644 --- a/assets/sass/_pages.scss +++ b/assets/sass/_pages.scss @@ -341,7 +341,7 @@ .hero { .bg { - background-image: url("../img/about/about-hero.jpg"); + background-image: url("../img/services/hero.jpg"); } } @@ -557,7 +557,7 @@ .hero { .bg { - background-image: url('../img/services/services-hero.jpg'); + background-image: url('../img/services/hero.jpg'); } } @@ -639,7 +639,7 @@ .products--page { .hero { .bg { - background-image: url('../img/products/products-hero.jpg'); + background-image: url('../img/products/hero.jpg'); } } @@ -760,7 +760,6 @@ ///////////////////////////// products page .product-details--page { - .hero { .bg { background-image: url('../img/products/products-hero.jpg'); @@ -782,14 +781,7 @@ } img { - width: 50%; - - @media (max-width: 1200px) { - width: 80%; - } - @media (max-width: 992px) { - width: 100%; - } + width: 100%; } } @@ -818,20 +810,28 @@ } #images { - margin-top: 250px; + margin-top: 80px; img { width: 60%; + min-height: 100px; + object-fit: cover; margin: 0 auto; cursor: pointer; + border: 3px solid transparent; + @extend %defaultTransition; + + &.selected { + border: 3px solid $red; + } } } } } .s2 { - margin-top: 100px; + margin-top: 200px; .parts { margin-top: 100px; @@ -877,6 +877,10 @@ &.p3 { text-align: center; + + img { + width: 100%; + } } &.p4 { @@ -1117,8 +1121,16 @@ text-align: right; margin-bottom: 30px; + span { + font-family: 'sahel', sans-serif; + } + &:lang(en) { text-align: left; + + span { + font-family: 'diodrum', sans-serif; + } } .category { @@ -1178,6 +1190,14 @@ text-align: center; margin-bottom: 80px; + span { + font-family: 'sahel', sans-serif; + + &:lang(en) { + font-family: 'diodrum', sans-serif; + } + } + .category { display: block; margin-bottom: 10px; @@ -1212,52 +1232,6 @@ } } } - - .content { - direction: rtl; - text-align: right; - - &:lang(en) { - direction: ltr; - text-align: left; - } - - a { - color: blue; - } - - p, a, span, b, ul, li, em, h1, h2, h3, h4, h5, h6, strong { - font-family: 'sahel', sans-serif; - direction: unset; - text-align: unset; - - &:lang(en) { - font-family: 'diodrum'; - direction: unset; - text-align: unset; - } - - &[dir="ltr"] { - direction: ltr; - text-align: left; - - p, a, span, b, ul, li, em, h1, h2, h3, h4, h5, h6, strong { - direction: ltr; - text-align: left; - } - } - - &[dir="rtl"] { - direction: rtl; - text-align: right; - - p, a, span, b, ul, li, em, h1, h2, h3, h4, h5, h6, strong { - direction: rtl; - text-align: right; - } - } - } - } } .s2 { @@ -1290,13 +1264,31 @@ li { margin-bottom: 30px; - i { - color: $red; - margin-left: 5px; + a { + @extend %defaultTransition; - &:lang(en) { - margin-left: 0; - margin-right: 5px; + &:hover { + color: $theme; + + b { + color: $theme; + } + } + + i { + color: $red; + margin-left: 5px; + + &:lang(en) { + margin-left: 0; + margin-right: 5px; + } + } + + .phone-number { + display: inline-block; + direction: ltr !important; + text-align: left; } } } @@ -1404,8 +1396,14 @@ list-style: decimal; list-style-position: outside; - p { + a { direction: ltr; + color: $theme; + @extend %defaultTransition; + + &:hover { + color: $red; + } } } } @@ -1421,6 +1419,17 @@ } } + &.gUsage { + img { + display: block; + margin-top: 50px; + margin-left: auto; + margin-right: auto; + width: 800px; + max-width: 100%; + } + } + h2 { margin-top: 80px; margin-bottom: 30px; @@ -1482,29 +1491,48 @@ .s2 { .app { + $appLayoutPadding: 55px; + @include transition(0.1s); .appTitle { text-align: center; + + .title { + font-size: 30px; + + @media (max-width: 1400px) { + font-size: 25px; + } + } } .appMethod { text-align: center; margin-bottom: 50px; - background: $red; + background: $theme; padding: 15px; + .txt { + display: inline-block; + margin: 0 10px 10px; + } + span { color: #fff; } .el-radio-button__orig-radio:checked + .el-radio-button__inner { background-color: $darkGray; - border-color: $darkGray; + border-color: #fff; @include boxShadow(-1px 0 0 0 $darkGray); } .el-radio-button .el-radio-button__inner { - color: $red; + color: $theme; + @extend %userSelect; + @media (max-width: 530px) { + font-size: 12px; + } } .el-radio-button.is-active .el-radio-button__inner { @@ -1513,8 +1541,8 @@ } .appLayout { - padding: 55px; - background: $red; + padding: $appLayoutPadding; + background: $theme; height: 100%; @include boxSizing(border-box); @@ -1608,6 +1636,10 @@ color: $darkGray; } } + + .err { + color: $red; + } } .el-input { @@ -1616,6 +1648,35 @@ //@media (max-width: 600px) { // width: 100%; //} + input { + font-family: 'sahel', 'diodrum', sans-serif; + + &:lang(en) { + font-family: 'diodrum', sans-serif; + } + + &::placeholder { + font-family: 'sahel'; + + &:lang(en) { + font-family: 'diodrum'; + } + } + } + + .el-input__suffix { + right: auto; + left: 5px; + + &:lang(en) { + right: 5px; + left: auto; + } + + .el-input__icon { + color: #000; + } + } } .el-select { @@ -1630,6 +1691,118 @@ margin-left: 20px; } } + + .appResult { + background: lightgray; + padding-left: $appLayoutPadding; + padding-right: $appLayoutPadding; + text-align: center; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + opacity: 0; + height: 0; + overflow: hidden; + + .success { + color: #67C23A; + } + + .failure { + color: $red; + } + + @keyframes waiting { + from { + opacity: 1; + } + + to { + opacity: 0; + } + } + + p { + font-size: 20px; + font-weight: bold; + } + + .waiting { + @include animation(waiting 0.7s alternate-reverse infinite); + } + } + } + } + + .s3 { + .notice { + color: red; + font-size: 14px; + display: none; + + @media (max-width: 992px) { + display: block; + } + } + + .tableBox { + width: 100%; + overflow: auto; + + table { + width: 100%; + min-width: 960px; + border: 1px solid rgba(#000, 1); + + thead { + background: $theme; + color: #fff; + + th { + padding: 20px; + font-family: 'sahel-LD', 'diodrum', sans-serif; + direction: ltr; + + &.middle { + border-left: 2px solid rgba(#fff, 0.4) !important; + border-right: 2px solid rgba(#fff, 0.4) !important; + } + } + } + + tbody { + background: rgba($theme, 0.2); + color: #000; + + tr { + line-height: 1.3em; + + td { + border: 1px solid rgba(#000, 1); + padding: 20px; + font-family: 'sahel-LD', 'diodrum', sans-serif; + direction: ltr; + text-align: center; + + &:last-child { + direction: ltr !important; + } + } + + &.odd { + background: rgba(#000, 0.1); + } + } + } + } + + &.vehicles { + } + + &.forklifts { + margin-top: 50px; + } } } } diff --git a/assets/sass/main.scss b/assets/sass/main.scss index 3ca0334..ebef3ac 100644 --- a/assets/sass/main.scss +++ b/assets/sass/main.scss @@ -1,3 +1,4 @@ +@import "CKEditorStyle"; @import "variables"; @import "mixins"; @import "extentions"; diff --git a/components/SiteFooterGlobal.vue b/components/SiteFooterGlobal.vue index 0adad9f..47dc651 100644 --- a/components/SiteFooterGlobal.vue +++ b/components/SiteFooterGlobal.vue @@ -1,53 +1,48 @@ diff --git a/components/SiteFooterHomePage.vue b/components/SiteFooterHomePage.vue index 9aa0ab2..fc8660d 100644 --- a/components/SiteFooterHomePage.vue +++ b/components/SiteFooterHomePage.vue @@ -1,53 +1,48 @@ diff --git a/components/SiteHeader.vue b/components/SiteHeader.vue index 663f67c..daa7516 100644 --- a/components/SiteHeader.vue +++ b/components/SiteHeader.vue @@ -1,176 +1,176 @@ diff --git a/components/admin/AdminAside.vue b/components/admin/AdminAside.vue index 3aff813..ba6e0c1 100644 --- a/components/admin/AdminAside.vue +++ b/components/admin/AdminAside.vue @@ -1,42 +1,42 @@ diff --git a/layouts/admin.vue b/layouts/admin.vue index ac31f9d..98c4bdc 100644 --- a/layouts/admin.vue +++ b/layouts/admin.vue @@ -1,45 +1,47 @@ diff --git a/layouts/default.vue b/layouts/default.vue index 486d138..74992df 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -1,43 +1,50 @@ diff --git a/middleware/redirects.js b/middleware/redirects.js index 72d8a99..49fe18a 100644 --- a/middleware/redirects.js +++ b/middleware/redirects.js @@ -1,11 +1,11 @@ export default function ({route, redirect, error}) { - ///////////// redirect to default local - if (route.path === '/') return redirect('/fa') - ///////////// local check - const lang = ['fa', 'en'] - const isLocal = lang.includes(route.params.lang) - const isAdmin = route.path.includes('/admin') + ///////////// redirect to default local + if (route.path === '/') return redirect('/fa') + ///////////// local check + const lang = ['fa', 'en'] + const isLocal = lang.includes(route.params.lang) + const isAdmin = route.path.includes('/admin') - if (isLocal || isAdmin) return null - else error({statusCode: 404, message: 'Page Not Found'}) + if (isLocal || isAdmin) return null + else error({statusCode: 404, message: 'Page Not Found'}) } diff --git a/nuxt.config.js b/nuxt.config.js index 1a3fed7..4f47c8b 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -1,92 +1,95 @@ const webpack = require("webpack") export default { - // Global page headers (https://go.nuxtjs.dev/config-head) - head: { - title: 'Arak Rail', - meta: [ - {charset: 'utf-8'}, - {name: 'viewport', content: 'width=device-width, initial-scale=1'}, - {hid: 'description', name: 'description', content: ''}, - {name: 'theme-color', content: '#303030'}, - ], - link: [ - {rel: 'icon', type: 'image/x-icon', href: '/favicon.png'} - ] - }, + // Global page headers (https://go.nuxtjs.dev/config-head) + head: { + title: 'اراک ریل', + meta: [ + {charset: 'utf-8'}, + {name: 'viewport', content: 'width=device-width, initial-scale=1'}, + {name: 'theme-color', content: '#303030'}, + ], + link: [ + {rel: 'icon', type: 'image/x-icon', href: '/favicon.png'} + ] + }, - // Global CSS (https://go.nuxtjs.dev/config-css) - loading: { - color: '#1B407C' - }, - css: [ - 'slick-carousel/slick/slick.css', - 'slick-carousel/slick/slick-theme.css', - 'element-ui/lib/theme-chalk/index.css', - '~/assets/css/bootstrap-grid.css', - '~/assets/css/reset-css.css', - '~/assets/css/fontawesome/css/all.min.css', - '~/assets/sass/main.scss' - ], + // Global CSS (https://go.nuxtjs.dev/config-css) + loading: { + color: '#1B407C' + }, + css: [ + 'slick-carousel/slick/slick.css', + 'slick-carousel/slick/slick-theme.css', + 'element-ui/lib/theme-chalk/index.css', + '~/assets/css/bootstrap-grid.css', + '~/assets/css/reset-css.css', + '~/assets/css/fontawesome/css/all.min.css', + '~/assets/sass/main.scss' + ], - // Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins) - plugins: [ - '@/plugins/element-ui', - '@/plugins/ckEditor.client', - '@/plugins/datePicker.client', - '@/plugins/gsap.client' - ], + // Plugins to run before rendering page (https://go.nuxtjs.dev/config-plugins) + plugins: [ + '@/plugins/element-ui', + '@/plugins/ckEditor.client', + '@/plugins/datePicker.client', + '@/plugins/gsap.client' + ], - // Auto import components (https://go.nuxtjs.dev/config-components) - components: true, + // Auto import components (https://go.nuxtjs.dev/config-components) + components: true, - // Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules) - buildModules: [], + // Modules for dev and build (recommended) (https://go.nuxtjs.dev/config-modules) + buildModules: [], - // Modules (https://go.nuxtjs.dev/config-modules) - modules: [ - // https://go.nuxtjs.dev/axios - '@nuxtjs/axios', - '@nuxtjs/auth' - ], + // Modules (https://go.nuxtjs.dev/config-modules) + modules: [ + // https://go.nuxtjs.dev/axios + '@nuxtjs/axios', + '@nuxtjs/auth' + ], - // Axios module configuration (https://go.nuxtjs.dev/config-axios) - axios: { - proxy: true - }, - proxy: { - '/api': {target: 'http://127.0.0.1:7320'} - }, + // Axios module configuration (https://go.nuxtjs.dev/config-axios) + axios: { + proxy: true + }, + proxy: { + '/api': {target: 'http://127.0.0.1:7320'} + }, - // Build Configuration (https://go.nuxtjs.dev/config-build) - build: { - transpile: [/^element-ui/], - vendor: ["jquery"], - plugins: [new webpack.ProvidePlugin({$: "jquery"})] - }, - router: { - middleware: ['redirects'], - linkActiveClass: 'active' - }, - server: { - host: '0.0.0.0', - port: 7320 - }, - serverMiddleware: ['~/api/index'], - auth: { - rewriteRedirects: true, - redirect: false, - strategies: { - local: { - endpoints: { - login: {url: '/api/auth/admin/login', method: 'post', propertyName: 'token'}, - logout: {url: '/api/auth/admin/logout', method: 'post'}, - user: {url: '/api/auth/admin/user', method: 'get', propertyName: 'user'} - }, - tokenRequired: true, - tokenType: '', - globalToken: true, - autoFetchUser: true - } + // Build Configuration (https://go.nuxtjs.dev/config-build) + build: { + transpile: [/^element-ui/], + + plugins: [new webpack.ProvidePlugin({ + $: 'jquery', + jQuery: 'jquery', + 'window.jQuery': 'jquery' + })] + }, + router: { + middleware: ['redirects'], + linkActiveClass: 'active' + }, + server: { + host: '0.0.0.0', + port: 7320 + }, + serverMiddleware: ['~/api/index'], + auth: { + rewriteRedirects: true, + redirect: false, + strategies: { + local: { + endpoints: { + login: {url: '/api/auth/admin/login', method: 'post', propertyName: 'token'}, + logout: {url: '/api/auth/admin/logout', method: 'post'}, + user: {url: '/api/auth/admin/user', method: 'get', propertyName: 'user'} + }, + tokenRequired: true, + tokenType: '', + globalToken: true, + autoFetchUser: true } - } + } + } } diff --git a/pages/_lang/about/index.vue b/pages/_lang/about/index.vue index b420d5d..56be4fd 100644 --- a/pages/_lang/about/index.vue +++ b/pages/_lang/about/index.vue @@ -1,167 +1,167 @@ diff --git a/pages/_lang/blog/_post.vue b/pages/_lang/blog/_post.vue index 533057a..d605e7a 100644 --- a/pages/_lang/blog/_post.vue +++ b/pages/_lang/blog/_post.vue @@ -1,96 +1,96 @@ diff --git a/pages/_lang/blog/index.vue b/pages/_lang/blog/index.vue index 6042064..343e56d 100644 --- a/pages/_lang/blog/index.vue +++ b/pages/_lang/blog/index.vue @@ -1,131 +1,131 @@ diff --git a/pages/_lang/calculation/index.vue b/pages/_lang/calculation/index.vue index dc7dda3..3566aac 100644 --- a/pages/_lang/calculation/index.vue +++ b/pages/_lang/calculation/index.vue @@ -1,224 +1,469 @@ diff --git a/pages/_lang/contact/index.vue b/pages/_lang/contact/index.vue index c365dde..1b0d43a 100644 --- a/pages/_lang/contact/index.vue +++ b/pages/_lang/contact/index.vue @@ -1,209 +1,210 @@ diff --git a/pages/_lang/index.vue b/pages/_lang/index.vue index 8884b21..19c981d 100644 --- a/pages/_lang/index.vue +++ b/pages/_lang/index.vue @@ -1,232 +1,231 @@ diff --git a/pages/_lang/products/_product.vue b/pages/_lang/products/_product.vue index c1a45be..7b766da 100644 --- a/pages/_lang/products/_product.vue +++ b/pages/_lang/products/_product.vue @@ -1,183 +1,185 @@ diff --git a/pages/_lang/products/index.vue b/pages/_lang/products/index.vue index 7702f66..f168dcc 100644 --- a/pages/_lang/products/index.vue +++ b/pages/_lang/products/index.vue @@ -1,121 +1,121 @@ diff --git a/pages/_lang/projects/index.vue b/pages/_lang/projects/index.vue index f035bf0..7603f87 100644 --- a/pages/_lang/projects/index.vue +++ b/pages/_lang/projects/index.vue @@ -1,117 +1,117 @@ diff --git a/pages/_lang/tech/gDesign.vue b/pages/_lang/tech/gDesign.vue index b858604..2ec84c1 100644 --- a/pages/_lang/tech/gDesign.vue +++ b/pages/_lang/tech/gDesign.vue @@ -1,49 +1,49 @@ diff --git a/pages/_lang/tech/gStandard.vue b/pages/_lang/tech/gStandard.vue index 7c8acf7..ab7e561 100644 --- a/pages/_lang/tech/gStandard.vue +++ b/pages/_lang/tech/gStandard.vue @@ -1,79 +1,67 @@ diff --git a/pages/_lang/tech/gTech.vue b/pages/_lang/tech/gTech.vue index 4986b95..8f72fed 100644 --- a/pages/_lang/tech/gTech.vue +++ b/pages/_lang/tech/gTech.vue @@ -1,5 +1,5 @@