const FileUpload = require('./fileupload') const PageTree = require('../page_tree') const api = require('../api') const Editor = require('./editor') const AdminEditPage = { oninit: function(vnode) { this.loading = false this.showLoading = null this.data = { page: null, } this.pages = [{id: null, name: 'Frontpage'}] this.pages = this.pages.concat(PageTree.getFlatTree()) this.newBanner = null this.newMedia = null this.editor = null this.fetchPage(vnode) }, onbeforeupdate: function(vnode) { if (this.lastid !== m.route.param('id')) { this.fetchPage(vnode) } }, fetchPage: function(vnode) { this.lastid = m.route.param('id') return this.requestPage( api.sendRequest({ method: 'GET', url: '/api/auth/pages/' + (this.lastid === 'add' ? '0' : this.lastid), }) ) }, requestPage: function(data) { this.error = '' if (this.showLoading) { clearTimeout(this.showLoading) } if (this.data.page) { this.showLoading = setTimeout(() => { this.showLoading = null this.loading = true m.redraw() }, 150) } else { this.loading = true } data .then((result) => { this.data = result if (this.data.page.id) { document.title = 'Editing: ' + this.data.page.name + ' - Admin NFP Moe' this.editedPath = true } else { document.title = 'Create Page - Admin NFP Moe' } }, (err) => { this.error = err.message }) .then(() => { if (!this.data.page) { this.data.page = {} } clearTimeout(this.showLoading) this.showLoading = null this.loading = false m.redraw() }) }, updateValue: function(name, e) { this.data.page[name] = e.currentTarget.value if (name === 'path') { this.editedPath = true } else if (name === 'name' && !this.editedPath) { this.data.page.path = this.data.page.name.toLowerCase().replace(/ /g, '-') } }, updateParent: function(e) { this.data.page.parent_id = Number(e.currentTarget.value) || null }, mediaUploaded: function(type, file) { if (type === 'banner') { this.newBanner = file } else { this.newMedia = file } }, mediaRemoved: function(type) { this.data.page['remove_' + type] = true this.data.page[type + '_prefix'] = null }, save: function(vnode, e) { e.preventDefault() if (!this.data.page.name) { this.error = 'Name is missing' } else if (!this.data.page.path) { this.error = 'Path is missing' } else { this.error = '' } if (this.error) return let formData = new FormData() if (this.newBanner) { formData.append('banner', this.newBanner.file) } if (this.newMedia) { formData.append('media', this.newMedia.file) } if (this.data.page.id) { formData.append('id', this.data.page.id) } formData.append('name', this.data.page.name) formData.append('parent_id', this.data.page.parent_id || null) formData.append('path', this.data.page.path) formData.append('remove_banner', this.data.page.remove_banner ? true : false) formData.append('remove_media', this.data.page.remove_media ? true : false) this.loading = true this.requestPage( this.editor.save() .then(body => { formData.append('content', JSON.stringify(body)) return api.sendRequest({ method: 'PUT', url: '/api/auth/pages/' + (this.lastid === 'add' ? '0' : this.lastid), body: formData, }) }) .then(data => { if (!data.page.id) { throw new Error('Something went wrong with saving, try again later') } else if (this.lastid === 'add') { this.lastid = data.page.id.toString() m.route.set('/admin/pages/' + data.page.id) } return PageTree.refreshTree().then(() => { this.pages = [{id: null, name: 'Frontpage'}] this.pages = this.pages.concat(PageTree.getFlatTree()) return data }) }) ) }, view: function(vnode) { let page = this.data.page let bannerImage = page && page.banner_alt_prefix ? page.banner_alt_prefix + '_large.avif' : null let mediaImage = page && page.media_alt_prefix ? page.media_alt_prefix + '_large.avif' : null return [ m('div.admin', [ !this.loading ? m(FileUpload, { class: 'banner', height: 150, onfile: this.mediaUploaded.bind(this, 'banner'), ondelete: this.mediaRemoved.bind(this, 'banner'), media: bannerImage, }, 'Click to upload banner image') : null, m('div.inside.vertical', { onsubmit: this.save.bind(this, vnode), }, [ m('div.page-goback', [ '« ', m(m.route.Link, { href: '/admin/pages' }, 'Pages') ]), m('h2', this.lastid === 'add' ? 'Create page' : 'Edit ' + (page && page.name || '(untitled)')), page ? m('div.actions', [ m('span', 'Actions:'), m(m.route.Link, { href: '/page/' + page.path }, 'View page'), ]) : null, m('div.error', { hidden: !this.error, onclick: function() { vnode.state.error = '' }, }, this.error), this.loading ? m('div.loading-spinner') : [ m(FileUpload, { class: 'cover', useimg: true, onfile: this.mediaUploaded.bind(this, 'media'), ondelete: this.mediaRemoved.bind(this, 'media'), media: mediaImage, }, 'Click to upload page image'), m('form', [ m('label', 'Parent'), m('select', { onchange: this.updateParent.bind(this), }, this.pages.filter(item => !page || item.id !== page.id).map((item) => { return m('option', { value: item.id || 0, selected: item.id === page.parent_id }, item.name) })), m('div.input-row', [ m('div', [ m('label', 'Name'), m('input', { type: 'text', value: page.name, oninput: this.updateValue.bind(this, 'name'), }), ]), m('div', [ m('label', 'Path'), m('input', { type: 'text', value: page.path, oninput: this.updateValue.bind(this, 'path'), }), ]), ]), m('label', 'Description'), m(Editor, { oncreate: (subnode) => { this.editor = subnode.state.editor }, contentdata: page.content, }), m('input', { hidden: !page.name || !page.path, type: 'submit', value: 'Save', }), ]) ], ]), ]), /* this.loading && !this.data.page ? m('div.admin-spinner.loading-spinner') : null, this.data.page ? m('div.admin-wrapper', [ this.loading ? m('div.loading-spinner') : null, m('div.admin-actions', this.data.page.id ? [ m('span', 'Actions:'), m(m.route.Link, { href: '/page/' + this.data.page.path }, 'View page'), ] : null), m('article.editarticle', [ m('header', m('h1', (this.data.page.id ? 'Edit ' : 'Create Page ') + (this.data.page.name || '(untitled)') ) ), m('div.error', { hidden: !this.error, onclick: () => { vnode.state.error = '' }, }, this.error), m(FileUpload, { height: 300, onfile: this.mediaUploaded.bind(this, 'banner'), ondelete: this.mediaRemoved.bind(this, 'banner'), media: bannerImage, }), m(FileUpload, { class: 'cover', useimg: true, onfile: this.mediaUploaded.bind(this, 'media'), ondelete: this.mediaRemoved.bind(this, 'media'), media: mediaImage, }), m('form.editarticle.content', { onsubmit: this.save.bind(this, vnode), }, [ m('label', 'Parent'), m('select', { onchange: this.updateParent.bind(this), }, this.pages.filter(item => !this.data.page || item.id !== this.data.page.id).map((item) => { return m('option', { value: item.id || 0, selected: item.id === this.data.page.parent_id }, item.name) })), m('div.input-row', [ m('div.input-group', [ m('label', 'Name'), m('input', { type: 'text', value: this.data.page.name, oninput: this.updateValue.bind(this, 'name'), }), ]), m('div.input-group', [ m('label', 'Path'), m('input', { type: 'text', value: this.data.page.path, oninput: this.updateValue.bind(this, 'path'), }), ]), ]), m('label', 'Description'), m(Editor, { oncreate: (subnode) => { this.editor = subnode.state.editor }, contentdata: this.data.page.content, }), m('div', { hidden: !this.data.page.name || !this.data.page.path }, [ m('input', { type: 'submit', value: 'Save', }), ]), ]), ]), ]) : m('div.error', { hidden: !this.error, onclick: () => { this.fetchPage(vnode) }, }, this.error),,*/ ] }, } module.exports = AdminEditPage