14 changed files with 421 additions and 16 deletions
@ -0,0 +1,138 @@ |
|||
// admin/attachment.js
|
|||
// Copyright (C) 2022 DTP Technologies, LLC
|
|||
// License: Apache-2.0
|
|||
|
|||
'use strict'; |
|||
|
|||
const express = require('express'); |
|||
|
|||
const { SiteController } = require('../../../lib/site-lib'); |
|||
|
|||
class AttachmentAdminController 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 = 'attachment'; |
|||
return next(); |
|||
}); |
|||
|
|||
router.param('attachmentId', this.populateAttachmentId.bind(this)); |
|||
|
|||
router.post('/:attachmentId', this.postUpdateAttachment.bind(this)); |
|||
|
|||
router.get('/create', this.getAttachmentEditor.bind(this)); |
|||
router.get('/:attachmentId', this.getAttachmentEditor.bind(this)); |
|||
|
|||
router.get('/', this.getDashboard.bind(this)); |
|||
|
|||
router.delete('/:attachmentId', this.deleteAttachment.bind(this)); |
|||
|
|||
return router; |
|||
} |
|||
|
|||
async populateAttachmentId (req, res, next, attachmentId) { |
|||
const { |
|||
attachment: attachmentService, |
|||
logan: loganService, |
|||
} = this.dtp.services; |
|||
try { |
|||
res.locals.attachment = await attachmentService.getById(attachmentId); |
|||
return next(); |
|||
} catch (error) { |
|||
loganService.sendRequestEvent(module.exports, req, { |
|||
level: 'error', |
|||
event: 'populateAttachmentId', |
|||
message: `failed to populate attachment: ${error.message}`, |
|||
data: { attachmentId, error }, |
|||
}); |
|||
return next(error); |
|||
} |
|||
} |
|||
|
|||
async postUpdateAttachment (req, res, next) { |
|||
const { |
|||
attachment: attachmentService, |
|||
logan: loganService, |
|||
} = this.dtp.services; |
|||
try { |
|||
await attachmentService.update(res.locals.attachment, req.body); |
|||
loganService.sendRequestEvent(module.exports, req, { |
|||
level: 'info', |
|||
event: 'postUpdateAttachment', |
|||
data: { |
|||
attachment: { |
|||
_id: res.locals.attachment._id, |
|||
}, |
|||
}, |
|||
}); |
|||
res.redirect('/admin/attachment'); |
|||
} catch (error) { |
|||
loganService.sendRequestEvent(module.exports, req, { |
|||
level: 'error', |
|||
event: 'postUpdateAttachment', |
|||
message: `failed to update attachment: ${error.message}`, |
|||
data: { error }, |
|||
}); |
|||
return next(error); |
|||
} |
|||
} |
|||
|
|||
async getAttachmentEditor (req, res) { |
|||
res.render('admin/attachment/editor'); |
|||
} |
|||
|
|||
async getDashboard (req, res, next) { |
|||
const { attachment: attachmentService } = this.dtp.services; |
|||
try { |
|||
res.locals.pagination = this.getPaginationParameters(req, 20); |
|||
res.locals.attachments = await attachmentService.getRecent(res.locals.pagination); |
|||
res.render('admin/attachment/index'); |
|||
} catch (error) { |
|||
return next(error); |
|||
} |
|||
} |
|||
|
|||
async deleteAttachment (req, res) { |
|||
const { |
|||
attachment: attachmentService, |
|||
logan: loganService, |
|||
} = this.dtp.services; |
|||
try { |
|||
const displayList = this.createDisplayList('delete-attachment'); |
|||
await attachmentService.remove(res.locals.attachment); |
|||
displayList.reload(); |
|||
|
|||
res.status(200).json({ success: true, displayList }); |
|||
|
|||
loganService.sendRequestEvent(module.exports, req, { |
|||
level: 'info', |
|||
event: 'deleteAttachment', |
|||
data: { attachment: { _id: res.locals.attachment._id } }, |
|||
}); |
|||
} catch (error) { |
|||
loganService.sendRequestEvent(module.exports, req, { |
|||
level: 'error', |
|||
event: 'deleteAttachment', |
|||
message: `failed to delete attachment: ${error.message}`, |
|||
data: { error }, |
|||
}); |
|||
res.status(error.statusCode || 500).json({ |
|||
success: false, |
|||
message: error.message, |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
name: 'adminAttachment', |
|||
slug: 'adminAttachment', |
|||
className: 'AttachmentAdminController', |
|||
create: async (dtp) => { return new AttachmentAdminController(dtp); }, |
|||
}; |
@ -0,0 +1,107 @@ |
|||
// admin/image.js
|
|||
// Copyright (C) 2022 DTP Technologies, LLC
|
|||
// License: Apache-2.0
|
|||
|
|||
'use strict'; |
|||
|
|||
const express = require('express'); |
|||
|
|||
const { SiteController } = require('../../../lib/site-lib'); |
|||
|
|||
class ImageAdminController 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 = 'image'; |
|||
return next(); |
|||
}); |
|||
|
|||
router.param('imageId', this.populateImageId.bind(this)); |
|||
|
|||
router.get('/:imageId', this.getImageView.bind(this)); |
|||
|
|||
router.get('/', this.getDashboard.bind(this)); |
|||
|
|||
router.delete('/:imageId', this.deleteImage.bind(this)); |
|||
|
|||
return router; |
|||
} |
|||
|
|||
async populateImageId (req, res, next, imageId) { |
|||
const { |
|||
image: imageService, |
|||
logan: loganService, |
|||
} = this.dtp.services; |
|||
try { |
|||
res.locals.image = await imageService.getImageById(imageId); |
|||
return next(); |
|||
} catch (error) { |
|||
loganService.sendRequestEvent(module.exports, req, { |
|||
level: 'error', |
|||
event: 'populateImageId', |
|||
message: `failed to populate image: ${error.message}`, |
|||
data: { imageId, error }, |
|||
}); |
|||
return next(error); |
|||
} |
|||
} |
|||
|
|||
async getImageView (req, res) { |
|||
res.render('admin/image/view'); |
|||
} |
|||
|
|||
async getDashboard (req, res, next) { |
|||
const { image: imageService } = this.dtp.services; |
|||
try { |
|||
res.locals.pagination = this.getPaginationParameters(req, 20); |
|||
res.locals.images = await imageService.getRecentImages(res.locals.pagination); |
|||
res.render('admin/image/index'); |
|||
} catch (error) { |
|||
return next(error); |
|||
} |
|||
} |
|||
|
|||
async deleteImage (req, res) { |
|||
const { |
|||
image: imageService, |
|||
logan: loganService, |
|||
} = this.dtp.services; |
|||
try { |
|||
const displayList = this.createDisplayList('delete-image'); |
|||
await imageService.deleteImage(res.locals.image); |
|||
displayList.reload(); |
|||
|
|||
res.status(200).json({ success: true, displayList }); |
|||
|
|||
loganService.sendRequestEvent(module.exports, req, { |
|||
level: 'info', |
|||
event: 'deleteImage', |
|||
data: { image: { _id: res.locals.image._id } }, |
|||
}); |
|||
} catch (error) { |
|||
loganService.sendRequestEvent(module.exports, req, { |
|||
level: 'error', |
|||
event: 'deleteImage', |
|||
message: `failed to delete image: ${error.message}`, |
|||
data: { error }, |
|||
}); |
|||
res.status(error.statusCode || 500).json({ |
|||
success: false, |
|||
message: error.message, |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
name: 'adminImage', |
|||
slug: 'adminImage', |
|||
className: 'ImageAdminController', |
|||
create: async (dtp) => { return new ImageAdminController(dtp); }, |
|||
}; |
@ -0,0 +1,21 @@ |
|||
extends ../layouts/main |
|||
block content |
|||
|
|||
h1 Attachments |
|||
|
|||
if Array.isArray(attachments) && (attachments.length > 0) |
|||
ul.uk-list.uk-list-divider |
|||
each attachment in attachments |
|||
li |
|||
div(uk-grid).uk-grid-small.uk-flex-middle |
|||
.uk-width-expand |
|||
//- had to abort while writing the renderer for an attachment. |
|||
//- will be back to finish this and have an attachment browser/manager. |
|||
pre= JSON.stringify(attachment, null, 2) |
|||
|
|||
.uk-width-auto |
|||
button(type="button", data-attachment-id= attachment._id, onclick="return dtp.adminApp.deleteAttachment(event);").uk-button.dtp-button-danger.uk-border-rounded |
|||
span |
|||
i.fas.fa-trash |
|||
else |
|||
div There are no attachments. |
@ -0,0 +1,45 @@ |
|||
extends ../layouts/main |
|||
block content |
|||
|
|||
include ../user/components/list-item |
|||
include ../../components/pagination-bar |
|||
|
|||
h1.uk-text-center Image Manager |
|||
|
|||
if Array.isArray(images.images) && (images.images.length > 0) |
|||
div(uk-grid).uk-flex-center |
|||
each image in images.images |
|||
.uk-width-medium |
|||
.uk-margin-small(uk-lightbox) |
|||
a(href=`/image/${image._id}`, data-type="image", data-caption=`id: ${image._id}`) |
|||
div |
|||
img(src= `/image/${image._id}`).responsive |
|||
|
|||
if image.owner |
|||
.uk-margin-small |
|||
+renderUserListItem(image.owner) |
|||
|
|||
.uk-margin-small.uk-text-center |
|||
button(type="button").uk-button.uk-button-default.uk-button-small.uk-border-rounded |
|||
span Image Menu |
|||
|
|||
div(uk-drop={ mode: 'click', pos: 'top-center' }).uk-card.uk-card-default.uk-card-small.uk-border-rounded |
|||
.uk-card-header |
|||
.uk-text-small.uk-text-muted.uk-text-center id:#{image._id} |
|||
.uk-card-body |
|||
ul.uk-nav.uk-dropdown-nav |
|||
li |
|||
a(href="#", data-image-id= image._id, onclick="dtp.adminApp.deleteImage(event);") |
|||
span |
|||
i.fas.fa-trash |
|||
span.uk-margin-small-left Delete image |
|||
li |
|||
a(href=`/admin/image/${image._id}/archive-user`).uk-text-truncate |
|||
span |
|||
i.fas.fa-file-archive |
|||
span.uk-margin-small-left Archive and ban #[span.uk-text-bold= image.owner.username] |
|||
|
|||
+renderPaginationBar('/admin/image', images.totalImageCount) |
|||
|
|||
else |
|||
.uk-text-center There are no images. |
Loading…
Reference in new issue