Rob Colbert
2 years ago
7 changed files with 221 additions and 5 deletions
@ -0,0 +1,112 @@ |
|||
// admin/card.js
|
|||
// Copyright (C) 2022 DTP Technologies, LLC
|
|||
// License: Apache-2.0
|
|||
|
|||
'use strict'; |
|||
|
|||
const DTP_COMPONENT_NAME = 'admin:card'; |
|||
|
|||
const express = require('express'); |
|||
|
|||
// const mongoose = require('mongoose');
|
|||
|
|||
const { SiteController, SiteError } = require('../../../lib/site-lib'); |
|||
|
|||
class CardController extends SiteController { |
|||
|
|||
constructor (dtp) { |
|||
super(dtp, DTP_COMPONENT_NAME); |
|||
} |
|||
|
|||
async start ( ) { |
|||
const router = express.Router(); |
|||
|
|||
router.use(async (req, res, next) => { |
|||
res.locals.currentView = 'admin'; |
|||
res.locals.adminView = 'card'; |
|||
return next(); |
|||
}); |
|||
|
|||
router.param('cardId', this.populateCardId.bind(this)); |
|||
|
|||
router.post('/:cardId', this.postCardUpdate.bind(this)); |
|||
router.post('/', this.postCardCreate.bind(this)); |
|||
|
|||
router.get('/create', this.getCardCreateForm.bind(this)); |
|||
|
|||
router.get('/:cardId', this.getCardView.bind(this)); |
|||
|
|||
router.get('/', this.getHomeView.bind(this)); |
|||
|
|||
return router; |
|||
} |
|||
|
|||
async populateCardId (req, res, next, cardId) { |
|||
const { card: cardService } = this.dtp.services; |
|||
try { |
|||
res.locals.card = await cardService.getById(cardId); |
|||
if (!res.locals.card) { |
|||
throw new SiteError(404, 'Card not found'); |
|||
} |
|||
return next(); |
|||
} catch (error) { |
|||
this.log.error('failed to populate card', { cardId, error }); |
|||
return next(error); |
|||
} |
|||
} |
|||
|
|||
async postCardUpdate (req, res, next) { |
|||
const { card: cardService } = this.dtp.services; |
|||
try { |
|||
await cardService.update(res.locals.card, req.body); |
|||
res.redirect(`/admin/card/${res.locals.card._id}`); |
|||
} catch (error) { |
|||
this.log.error('failed to update card', { |
|||
cardId: res.locals.card._id, |
|||
error, |
|||
}); |
|||
return next(error); |
|||
} |
|||
} |
|||
|
|||
async postCardCreate (req, res, next) { |
|||
const { card: cardService } = this.dtp.services; |
|||
try { |
|||
res.locals.card = await cardService.create(req.user, req.body); |
|||
res.redirect(`/admin/card/${res.locals.card._id}`); |
|||
} catch (error) { |
|||
this.log.error('failed to create card', { |
|||
cardId: res.locals.card._id, |
|||
error, |
|||
}); |
|||
return next(error); |
|||
} |
|||
} |
|||
|
|||
async getCardView (req, res) { |
|||
res.render('admin/card/editor'); |
|||
} |
|||
|
|||
async getCardCreateForm (req, res) { |
|||
res.render('admin/card/editor'); |
|||
} |
|||
|
|||
async getHomeView (req, res, next) { |
|||
const { card: cardService } = this.dtp.services; |
|||
try { |
|||
res.locals.pagination = this.getPaginationParameters(req, 20); |
|||
res.locals.cards = await cardService.getCards(res.locals.pagination); |
|||
res.render('admin/card/index'); |
|||
} catch (error) { |
|||
this.log.error('failed to create card', { |
|||
error, |
|||
}); |
|||
return next(error); |
|||
} |
|||
} |
|||
} |
|||
|
|||
module.exports = async (dtp) => { |
|||
let controller = new CardController(dtp); |
|||
return controller; |
|||
}; |
@ -0,0 +1,99 @@ |
|||
// card.js
|
|||
// Copyright (C) 2022 DTP Technologies, LLC
|
|||
// License: Apache-2.0
|
|||
|
|||
'use strict'; |
|||
|
|||
const mongoose = require('mongoose'); |
|||
|
|||
// const Card = mongoose.model('Card');
|
|||
const Card = mongoose.model('Card'); |
|||
|
|||
const striptags = require('striptags'); |
|||
|
|||
const { SiteService } = require('../../lib/site-lib'); |
|||
|
|||
class CardService extends SiteService { |
|||
|
|||
constructor (dtp) { |
|||
super(dtp, module.exports); |
|||
|
|||
this.populateCard = [ |
|||
{ |
|||
path: 'owner', |
|||
select: 'created username username_lc displayName picture', |
|||
}, |
|||
]; |
|||
} |
|||
|
|||
async create (owner, cardDefinition) { |
|||
const NOW = new Date(); |
|||
const card = new Card(); |
|||
|
|||
card.created = NOW; |
|||
card.owner = owner._id; |
|||
card.name = striptags(cardDefinition.name.trim()); |
|||
card.name_lc = card.name.toLowerCase(); |
|||
card.description = striptags(cardDefinition.description.trim()); |
|||
|
|||
if (cardDefinition.tags) { |
|||
card.tags = cardDefinition.tags.split(',').map((tag) => tag.trim()); |
|||
} |
|||
|
|||
card.flags = { |
|||
isOfficial: cardDefinition.isOfficial === 'on', |
|||
}; |
|||
|
|||
await card.save(); |
|||
|
|||
return card.toObject(); |
|||
} |
|||
|
|||
async update (card, cardDefinition) { |
|||
|
|||
cardDefinition.name = striptags(cardDefinition.name.trim()); |
|||
cardDefinition.name_lc = cardDefinition.name.toLowerCase(); |
|||
cardDefinition.description = striptags(cardDefinition.description.trim()); |
|||
if (cardDefinition.tags) { |
|||
cardDefinition.tags = cardDefinition.tags.split(',').map((tag) => tag.trim()); |
|||
} |
|||
|
|||
await Card.updateOne( |
|||
{ _id: card._id }, |
|||
{ |
|||
$set: { |
|||
name: cardDefinition.name, |
|||
name_lc: cardDefinition.name_lc, |
|||
description: cardDefinition.description, |
|||
tags: cardDefinition.tags, |
|||
'flags.isOfficial': cardDefinition.isOfficial === 'on', |
|||
}, |
|||
}, |
|||
); |
|||
} |
|||
|
|||
async getCards (pagination) { |
|||
const cards = await Card |
|||
.find() |
|||
.sort({ created: -1 }) |
|||
.skip(pagination.skip) |
|||
.limit(pagination.cpp) |
|||
.populate(this.populateCard) |
|||
.lean(); |
|||
return cards; |
|||
} |
|||
|
|||
async getById (cardId) { |
|||
const card = await Card |
|||
.findOne({ _id: cardId }) |
|||
.populate(this.populateCard) |
|||
.lean(); |
|||
return card; |
|||
} |
|||
} |
|||
|
|||
module.exports = { |
|||
slug: 'card', |
|||
name: 'card', |
|||
create: (dtp) => { return new CardService(dtp); }, |
|||
}; |
@ -0,0 +1,4 @@ |
|||
extends ../layouts/main |
|||
block content |
|||
|
|||
h1 Stuff |
Loading…
Reference in new issue