// admin/page.js // Copyright (C) 2021 Digital Telepresence, LLC // License: Apache-2.0 'use strict'; const express = require('express'); const { SiteController, SiteError } = require('../../../lib/site-lib'); class PageController extends SiteController { constructor (dtp) { super(dtp, module.exports); } async start ( ) { const router = express.Router(); router.use(async (req, res, next) => { res.locals.currentView = 'admin'; res.locals.adminView = 'page'; return next(); }); router.param('pageId', this.populatePageId.bind(this)); router.post('/:pageId', this.pageUpdatePage.bind(this)); router.post('/', this.pageCreatePage.bind(this)); router.get('/compose', this.getComposer.bind(this)); router.get('/:pageId', this.getComposer.bind(this)); router.get('/', this.getIndex.bind(this)); router.delete('/:pageId', this.deletePage.bind(this)); return router; } async populatePageId (req, res, next, pageId) { const { page: pageService } = this.dtp.services; try { res.locals.page = await pageService.getById(pageId); if (!res.locals.page) { throw new SiteError(404, 'Page not found'); } return next(); } catch (error) { this.log.error('failed to populate pageId', { pageId, error }); return next(error); } } async pageUpdatePage (req, res, next) { const { page: pageService } = this.dtp.services; try { await pageService.update(req.user, res.locals.page, req.body); res.redirect('/admin/page'); } catch (error) { this.log.error('failed to update page', { newletterId: res.locals.page._id, error }); return next(error); } } async pageCreatePage (req, res, next) { const { page: pageService } = this.dtp.services; try { await pageService.create(req.user, req.body); res.redirect('/admin/page'); } catch (error) { this.log.error('failed to create page', { error }); return next(error); } } async getComposer (req, res, next) { const { page: pageService } = this.dtp.services; try { let excludedPages; if (res.locals.page) { excludedPages = [res.locals.page._id]; } res.locals.availablePages = await pageService.getAvailablePages(excludedPages); res.render('admin/page/editor'); } catch (error) { this.log.error('failed to serve page editor', { error }); return next(error); } } async getIndex (req, res, next) { const { page: pageService } = this.dtp.services; try { res.locals.pagination = this.getPaginationParameters(req, 20); res.locals.pages = await pageService.getPages(res.locals.pagination, ['draft', 'published', 'archived']); res.render('admin/page/index'); } catch (error) { this.log.error('failed to fetch pages', { error }); return next(error); } } async deletePage (req, res) { const { page: pageService } = this.dtp.services; try { const displayList = this.createDisplayList('delete-page'); await pageService.deletePage(res.locals.page); displayList.removeElement(`li[data-page-id="${res.locals.page._id}"]`); displayList.showNotification( `Page "${res.locals.page.title}" deleted`, 'success', 'bottom-center', 3000, ); res.status(200).json({ success: true, displayList }); } catch (error) { this.log.error('failed to delete page', { pageId: res.local.page._id, error, }); res.status(error.statusCode || 500).json({ success: false, message: error.message, }); } } } module.exports = { name: 'adminPage', slug: 'admin-page', create: async (dtp) => { return new PageController(dtp); }, };