From 84542228a3da3ee7730658ce1cb0eb0830e003b8 Mon Sep 17 00:00:00 2001 From: Ro Date: Mon, 25 Nov 2019 13:58:34 -0800 Subject: [PATCH] cleaned up libraries file, polished page updating, added page creation --- .eslintrc | 3 +- brain/api/v1/auth.js | 32 +------------ brain/api/v1/pages.js | 37 ++++++++------- brain/routes/dash/pages.js | 46 +++++++++++++----- brain/views/page-edit.pug | 28 ++--------- brain/views/partials/editor.pug | 2 +- brain/views/partials/front.pug | 4 +- package-lock.json | 46 ++++++++++++++++++ package.json | 3 +- src/com/actions/PageActions.js | 79 +------------------------------ src/com/controllers/PageEditor.js | 34 ++++++------- 11 files changed, 130 insertions(+), 184 deletions(-) diff --git a/.eslintrc b/.eslintrc index eaa376a..a1f75dd 100644 --- a/.eslintrc +++ b/.eslintrc @@ -64,6 +64,7 @@ "globals": { "_": false, "hljs": false, - "Sortable": false + "Sortable": false, + "Prism": false } } \ No newline at end of file diff --git a/brain/api/v1/auth.js b/brain/api/v1/auth.js index 466f7d0..f74d949 100644 --- a/brain/api/v1/auth.js +++ b/brain/api/v1/auth.js @@ -48,40 +48,10 @@ router.post('/login', function(req, res) { } else { res.json({ type: DataEvent.REQUEST_LAME, - message: 'MEMBER NOT FOUND' + message: 'Need to see some id, champ.' }); } }); - - /** - Models.User.findOne({ - where: { - handle: req.body.handle - } - }) - .then(user => { - if (!isValidPassword(user, req.body.password)) { - return res.json({ - message: 'CHECK YOUR PASSWORD' - }); - } - - let token = jwt.sign({ id: user._id }, 'super-secret-string', { - expiresIn: 86400 // expires in 24 hours - }); - - let session = req.session; - session.user = user; - session.token = token; - - res.json({ auth: 'Yes', token: session.token }); - }) - .catch(() => { - return res.json({ - message: 'NOT FOUND, HAWS' - }); - }); - **/ }); //router.post('/logout', function(req, res) {}); diff --git a/brain/api/v1/pages.js b/brain/api/v1/pages.js index 5d9315d..fac1782 100644 --- a/brain/api/v1/pages.js +++ b/brain/api/v1/pages.js @@ -1,23 +1,13 @@ import Book from '../../data/Book'; -import StringUtils from '../../../src/com/utils/StringUtils'; import * as DataEvent from '../../../src/com/events/DataEvent'; -import sanitize from 'sanitize-html'; -import RightsManager, { - TASK_CREATE, - TASK_UPDATE, - OBJECT_POST -} from '../../../src/com/utils/RightsManager'; const express = require('express'); const router = express.Router(); const multer = require('multer'); -const md = require('markdown-it')('commonmark'); const fs = require('fs-extra'); const moment = require('moment'); -const rightsManager = new RightsManager(); const book = new Book(); const uploadPath = './public/assets/images/blog/' + moment().format('YYYY') + '/' + moment().format('MM'); -const _ = require('lodash'); fs.ensureDir(uploadPath, () => { // dir has now been created, including the directory it is to be placed in }); @@ -50,12 +40,16 @@ router.get('/', (req, res) => { /*** Update Page */ -router.post('/write', feature_upload, (req, res) => { +router.post('/write/:task?', feature_upload, (req, res) => { var feature = ''; - if (req.files.lengh > 0) { + if (req.files.length > 0) { + var path = req.files[0].path; + feature = '/' + path.substring(7, path.length); } else { var url = req.body.feature_image; - feature = url.substring(21, url.length); + url != null || url != undefined || url != '' + ? (feature = url.substring(21, url.length)) + : (feature = ''); } var pageWrite = @@ -82,11 +76,14 @@ router.post('/write', feature_upload, (req, res) => { req.session.user.handle + '\n' + 'created: ' + - req.body.created + + moment(req.body.created).format() + '\n' + 'updated: ' + moment(Date.now()).format() + '\n' + + 'menu: ' + + req.body.pinToMenu + + '\n' + 'featured: ' + req.body.featureStatus + '\n' + @@ -98,12 +95,20 @@ router.post('/write', feature_upload, (req, res) => { '\n' + '---\n\n' + req.body.content; - fs.writeFile('content/pages/test.md', pageWrite, err => { + fs.writeFile('content/pages/' + req.body.slug + '.md', pageWrite, err => { // throws an error, you could also catch it here if (err) res.json({ type: DataEvent.PAGE_ERROR, message: err }); // success case, the file was saved - res.json({ type: DataEvent.PAGE_UPDATED, message: 'Page Has been saved' }); + if (req.params.task === 'new') { + res.json({ + type: DataEvent.PAGE_ADDED, + message: 'New Page Created', + id: req.body.page_uuid + }); + } else { + res.json({ type: DataEvent.PAGE_UPDATED, message: 'Page Has been saved' }); + } }); }); diff --git a/brain/routes/dash/pages.js b/brain/routes/dash/pages.js index aab43d9..b82b1f2 100644 --- a/brain/routes/dash/pages.js +++ b/brain/routes/dash/pages.js @@ -3,9 +3,11 @@ const express = require('express'); const router = express.Router(); const hljs = require('highlight.js/lib/highlight'); const hljs_md = require('highlight.js/lib/languages/markdown'); -hljs.registerLanguage('markdown', hljs_md); const moment = require('moment'); const book = new Book(); +const uuidv4 = require('uuid/v4'); +const fs = require('fs-extra'); +hljs.registerLanguage('markdown', hljs_md); //-------------------------- // POSTS //-------------------------- @@ -33,15 +35,35 @@ router.get('/list/:filter?/:page?', function(req, res) { //-------------------------- router.get('/add/new', function(req, res) { if (req.session.user) { - res.render('dash/post-edit', { - title: 'Dashboard New Post', - user_status: true, - welcome: 'New Post', - mode: 'admin', - date: '', - status: ['false', 'false', 'false'], - edit: false - }); + fs.readJSON('site/settings.json') + .then(settings => { + //use current index as id, then updated current index and page count + + let pageID = settings.library_stats.current_index; + settings.library_stats.current_index = ++settings.library_stats.current_index; + settings.library_stats.total_pages = ++settings.library_stats.total_pages; + fs.writeJson('site/settings.json', settings) + .then(() => { + res.render('page-edit', { + id: pageID, + uuid: uuidv4(), + title: 'Add New Page', + user_status: true, + welcome: 'Add New Page', + date: moment(Date.now()).format('YYYY MMM DD'), + page: [], + rawDate: Date.now(), + status: ['false', 'false', 'false'], + edit: false + }); + }) + .catch(err => { + console.error('SAVING', err); + }); + }) + .catch(err => { + console.log('READING', err); + }); } else { res.redirect('/@/dashboard'); } @@ -59,16 +81,14 @@ router.get('/edit/:id', function(req, res) { id: page.metadata.id, uuid: page.metadata.uuid, title: 'Edit Page', - user_status: true, welcome: 'Edit Page', - mode: 'admin', page: page.metadata, date: moment(page.metadata.created).format('YYYY MMM DD'), rawDate: page.metadata.created, colored: pretty, feature: page.metadata.feature, status: [ - String(true), + String(page.metadata.menu), String(page.metadata.featured), String(page.metadata.published) ], diff --git a/brain/views/page-edit.pug b/brain/views/page-edit.pug index 72c1f37..24e387e 100644 --- a/brain/views/page-edit.pug +++ b/brain/views/page-edit.pug @@ -1,23 +1,5 @@ extends frame block main-content - // move this to backend - -var post_title = '' - -var post_plaintext = '' - -var post_feature = 'null' - -var post_tags = '' - -var post_id = '' - -var post_date = date - -var post_status = ['false', 'false', 'false',] - - if(edit) - -post_title = page.title - -post_plaintext = page.plaintext - -post_feature = page.feature - -post_tags = page.tags - -post_date = date - -post_status = status - - form#test-form #post-edit-index(data-index=id data-uuid=uuid) #post-edit-index-wrapper //h2 EDIT @@ -35,17 +17,17 @@ block main-content svg#new-feature-upload(viewBox="0 0 20 20" class="icons") use(xlink:href='/assets/images/global/sprite.svg#entypo-image-inverted') #featured-image-drop - img#featured-image(src=post_feature) + img#featured-image(src=page.feature) #post-header.columns #post-title.column textarea(id="post_title" type='text', name='post_title' class='post-edit', placeholder='title', required, autofocus) - =post_title + =page.title #calendar-icon svg(viewBox="0 0 20 20" class="icons") use(xlink:href='/assets/images/global/sprite.svg#entypo-calendar') - input(id="post-date" type="text" value=post_date data-raw=rawDate) + input(id="post-date" type="text" value=date data-raw=rawDate) #post-options - button#option-page.option-inactive.post-option-btn(data-active= status[0]) + button#option-menu-pin.option-inactive.post-option-btn(data-active= status[0]) svg#option-page-icon(viewBox="0 0 20 20" class="icons") use#option-page-icon(xlink:href='/assets/images/global/sprite.svg#entypo-pin') button#option-feature.option-inactive.post-option-btn(data-active= status[1]) @@ -59,7 +41,7 @@ block main-content use#option-preview-icon(xlink:href='/assets/images/global/sprite.svg#entypo-eye') #post-meta.column textarea(id='post_tags' type='text', name='post_tags' class='form-control', placeholder='tags [comma seperated]', autofocus) - =post_tags + =page.tags include partials/editor input(id="featured-image-upload" type="file" name="featured-image-upload") input(id="post-image-upload" type="file" name="post-image-upload") diff --git a/brain/views/partials/editor.pug b/brain/views/partials/editor.pug index 6f520ef..f3de507 100644 --- a/brain/views/partials/editor.pug +++ b/brain/views/partials/editor.pug @@ -32,6 +32,6 @@ else button#edit-save.post-sumbit-btn.submit-start.editor-button(data-action='blog-add' type='submit') svg#submit-save(viewBox="0 0 20 20" class="icons") - use#submit-save(xlink:href='/dash/assets/images/sprite.svg#entypo-plus' data-action='blog-add') + use#submit-save(xlink:href='/assets/images/global/sprite.svg#entypo-plus' data-action='blog-add') \ No newline at end of file diff --git a/brain/views/partials/front.pug b/brain/views/partials/front.pug index 99f4c67..ee73e97 100644 --- a/brain/views/partials/front.pug +++ b/brain/views/partials/front.pug @@ -3,9 +3,9 @@ .recent-header h3 Recent .index-menu - a(href='/@/dashboard/posts/list') View Posts + a(href='/@/dashboard/page/list') View Pages | . - a(href='/@/dashboard/posts/add/new') Create Post + a(href='/@/dashboard/page/add/new') Create Page br - var index = 0; - var cap = 5; // number of posts to display, get rid of this and put it in the config diff --git a/package-lock.json b/package-lock.json index 887fa42..8f9b1ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2228,6 +2228,17 @@ "source-map": "~0.6.0" } }, + "clipboard": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.4.tgz", + "integrity": "sha512-Vw26VSLRpJfBofiVaFb/I8PVfdI1OxKcYShe6fm0sP/DtmiWQNCjhM/okTvdCo0G+lMMm1rMYbk4IK4x1X+kgQ==", + "optional": true, + "requires": { + "good-listener": "^1.2.2", + "select": "^1.1.2", + "tiny-emitter": "^2.0.0" + } + }, "cliui": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", @@ -2567,6 +2578,12 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delegate": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", + "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", + "optional": true + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -3900,6 +3917,15 @@ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, + "good-listener": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", + "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "optional": true, + "requires": { + "delegate": "^3.1.2" + } + }, "graceful-fs": { "version": "4.1.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", @@ -5350,6 +5376,14 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, + "prismjs": { + "version": "1.17.1", + "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.17.1.tgz", + "integrity": "sha512-PrEDJAFdUGbOP6xK/UsfkC5ghJsPJviKgnQOoxaDbBjwc8op68Quupwt1DeAFoG8GImPhiKXAvvsH7wDSLsu1Q==", + "requires": { + "clipboard": "^2.0.0" + } + }, "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", @@ -5855,6 +5889,12 @@ "integrity": "sha1-io6pbtN0G4WpKgSCQuniBxyePLE=", "dev": true }, + "select": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", + "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", + "optional": true + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -6363,6 +6403,12 @@ "resolved": "https://registry.npmjs.org/tiny-date-picker/-/tiny-date-picker-3.2.8.tgz", "integrity": "sha512-XrZ2ujRDZLom3DtquzjtEh+kBLbivErqfbqbNG8sVA7ZCUxerIiorxfM87akQNbBnKttBaiXAZwZi46e2mFX7Q==" }, + "tiny-emitter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", + "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", + "optional": true + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", diff --git a/package.json b/package.json index 2f87496..1a29a15 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "watch-front": "stylus -w -m -o themes/$npm_package_theme/assets/css themes/$npm_package_theme/src/styles/base.styl & parcel watch themes/$npm_package_theme/src/com/Start.js --out-dir themes/$npm_package_theme/assets/js --out-file start.min.js --public-url /$npm_package_theme/assets/js", "build-front-kit": "uglifyjs node_modules/scramble-text/dist/ScrambleText.min.js node_modules/animejs/anime.min.js node_modules/reframe.js/dist/reframe.min.js -c -o themes/$npm_package_theme/assets/js/toolkit.min.js", "watch-back": "stylus -w -m -o public/assets/css src/styles/dash.styl & parcel watch src/com/Start.js --out-dir public/assets/scripts --out-file dash.min.js --public-url /assets/scripts", - "build-back-kit": "uglifyjs src/libraries/highlight.pack.js node_modules/sortablejs/Sortable.min.js node_modules/scramble-text/dist/ScrambleText.min.js node_modules/animejs/anime.min.js node_modules/reframe.js/dist/reframe.min.js -c -o themes/dash/assets/js/dashkit.min.js" + "build-back-kit": "uglifyjs src/libraries/highlight.pack.js node_modules/sortablejs/Sortable.min.js node_modules/scramble-text/dist/ScrambleText.min.js node_modules/reframe.js/dist/reframe.min.js -c -o public/assets/scripts/dashkit.min.js" }, "engines": { "node": ">=10.16.0" @@ -47,6 +47,7 @@ "nodemailer-mailgun-transport": "^1.4.0", "pg": "^7.12.1", "pg-hstore": "^2.3.3", + "prismjs": "^1.17.1", "pug": "latest", "reframe.js": "^2.2.5", "request": "^2.88.0", diff --git a/src/com/actions/PageActions.js b/src/com/actions/PageActions.js index e277930..ba972ce 100644 --- a/src/com/actions/PageActions.js +++ b/src/com/actions/PageActions.js @@ -1,7 +1,6 @@ import DataUtils, { REQUEST_TYPE_POST, CONTENT_TYPE_JSON } from '../utils/DataUtils'; import StringUtils from '../utils/StringUtils'; import * as DataEvent from '../events/DataEvent'; -var uuidv4 = require('uuid/v4'); export default class PostActions { //-------------------------- // constructor @@ -40,8 +39,8 @@ export default class PostActions { ); pageInfo.append('tags', document.getElementById('post_tags').value); pageInfo.append( - 'pageStatus', - document.getElementById('option-page').getAttribute('data-active') + 'pinToMenu', + document.getElementById('option-menu-pin').getAttribute('data-active') ); pageInfo.append( 'featureStatus', @@ -68,80 +67,6 @@ export default class PostActions { resolve(pageInfo); }); } - update(id, data, files, lastKey) { - let self = this; - let freshData; - return new Promise(function(resolve, reject) { - let txt = document.createElement('textarea'); - txt.innerHTML = document.getElementById('edit-post-text').innerHTML; - let html = txt.value; - html = html.replace(/<\/?span[^>]*>/g, ''); //removes highightjs styling - html = html.replace(/<\/?br[^>]*>/g, '\n'); //convert back to encoded line break for storage - data.title = document.getElementById('post_title').value; - data.slug = new StringUtils().cleanString(document.getElementById('post_title').value); - data.plaintext = html; - data.html = html; - data.created = document.getElementById('post-date').value; - data.tags = document.getElementById('post_tags').value; - data.page = document.getElementById('option-page').getAttribute('data-active'); - data.featured = document.getElementById('option-feature').getAttribute('data-active'); - data.published = document - .getElementById('option-published') - .getAttribute('data-active'); - if (files.length != 0) { - for (var i = 0; i < files.length; i++) { - var file = files[i]; - // Check the file type. - if (!file.type.match('image.*')) { - continue; - } - data.feature = - '/content/blog-images/' + - self.dateUtils.getDate('year', new Date()) + - '/' + - self.dateUtils.getDate('month', new Date()) + - '/' + - file.name; - } - } else { - if (typeof data.feature == 'undefined') data.feature = ''; - } - if (id == null) { - freshData = { - id: lastKey + 1, - post: { - uuid: uuidv4(), - title: data.title, - slug: data.slug, - plaintext: data.plaintext, - html: data.html, - feature: data.feature, - created: data.created, - tags: data.tags, - page: data.page, - featured: data.featured, - published: data.published, - deleted: '', - author: 'user' - } - }; - } else { - freshData = data; - } - self.dbUtils - .modify(id, freshData) - .then(response => { - resolve(response); - if (id != null) - freshData.page == 'true' - ? self.updateNav(true, id, freshData) - : self.updateNav(false, id, freshData); - }) - .catch(err => { - reject(err); - }); - }); - } deletePost(id, body) { let self = this; body.deleted = new Date().toString(); diff --git a/src/com/controllers/PageEditor.js b/src/com/controllers/PageEditor.js index d66fb7b..b92b979 100644 --- a/src/com/controllers/PageEditor.js +++ b/src/com/controllers/PageEditor.js @@ -9,8 +9,6 @@ import Notfications from '../ui/Notifications'; const data = new DataUtils(); const notify = new Notfications(); export default class PostEditor { - //TODO - FIX POST FEATURE URLS IN DB - //-------------------------- // constructor //-------------------------- @@ -59,6 +57,7 @@ export default class PostEditor { TinyDatePicker(document.getElementById('post-date'), { mode: 'dp-below', format(date) { + console.log('RAW DATE', date); return self.dateUtils.getDate('origin', date); } }); @@ -98,8 +97,8 @@ export default class PostEditor { let currentOption; switch (e.target.id) { case 'option-page-icon': - case 'option-page': - currentOption = document.getElementById('option-page'); + case 'option-menu-pin': + currentOption = document.getElementById('option-menu-pin'); break; case 'option-feature-icon': case 'option-feature': @@ -119,25 +118,17 @@ export default class PostEditor { let self = this; switch (e) { case EditorEvent.EDITOR_SAVE: - new PageActions() - .update(this.postID, this.post, PostEditor.uploadFiles, FINAL_KEY) - .then(response => { - setTimeout(() => { - self.dbUtils.getPost(Number(response.response.newPost)).then(r => { - window.location = '/@/dashboard/posts/edit/' + r.post.uuid; - }); - }, 100); - }) - .catch(() => { - //console.log("ERROR", err) - }); - break; case EditorEvent.EDITOR_UPDATE: + var apiUrl = ''; + e === EditorEvent.EDITOR_SAVE + ? (apiUrl = '/api/v1/page/write/new') + : (apiUrl = '/api/v1/page/write'); new PageActions() .collectInfo(document.getElementById('featured-image-upload').files[0]) + .then(page => { data.request( - '/api/v1/page/write', + apiUrl, DataEvent.API_PAGE_WRITE, REQUEST_TYPE_POST, CONTENT_TYPE_FORM, @@ -148,7 +139,12 @@ export default class PostEditor { if (r.type === DataEvent.PAGE_ERROR) { notify.alert(r.message, false); } else { - notify.alert(r.message, true); + if (r.type === DataEvent.PAGE_UPDATED) { + notify.alert(r.message, true); + } else { + notify.alert(r.message, true); + window.location = '/@/dashboard/page/edit/' + r.id; + } } }) .catch(err => {