From b382af802e1b61a4b93265e32ea07b907b5a402c Mon Sep 17 00:00:00 2001 From: rob Date: Fri, 8 Jul 2022 00:03:22 -0400 Subject: [PATCH] progress on post user services --- app/controllers/author.js | 6 ++- app/controllers/post.js | 6 ++- app/models/post.js | 11 ++++- app/services/post.js | 19 +++++--- app/services/user.js | 6 ++- app/views/author/index.pug | 59 +++++++++++++++++++++---- app/views/components/off-canvas.pug | 9 ++++ app/views/index.pug | 3 +- app/views/post/components/list-item.pug | 8 ++-- app/views/post/editor.pug | 2 +- app/views/post/view.pug | 2 +- 11 files changed, 103 insertions(+), 28 deletions(-) diff --git a/app/controllers/author.js b/app/controllers/author.js index bb12cda..28f3a23 100644 --- a/app/controllers/author.js +++ b/app/controllers/author.js @@ -43,9 +43,11 @@ class AuthorController extends SiteController { } async getAuthorHome (req, res, next) { - const { post: postService } = this.dtp.services; + const { /*comment: commentService,*/ post: postService } = this.dtp.services; try { - res.locals.drafts = await postService.getAuthorDrafts(req.user); + res.locals.drafts = await postService.getForAuthor(req.user, 'draft'); + res.locals.posts = await postService.getForAuthor(req.user, 'published', 4); + // res.locals.comments = await commentService.getForResource. res.render('author/index'); } catch (error) { this.log.error('failed to render Author dashboard', { error }); diff --git a/app/controllers/post.js b/app/controllers/post.js index ca80539..beb85a6 100644 --- a/app/controllers/post.js +++ b/app/controllers/post.js @@ -56,7 +56,7 @@ class PostController extends SiteController { router.post('/', requireAuthorPrivileges, this.postCreatePost.bind(this)); - router.get('/:postId/edit', requireAuthorPrivileges, this.getComposer.bind(this)); + router.get('/:postId/edit', requireAuthorPrivileges, this.getEditor.bind(this)); router.get('/compose', requireAuthorPrivileges, this.getComposer.bind(this)); router.get('/:postSlug/comment', @@ -272,6 +272,10 @@ class PostController extends SiteController { } } + async getEditor (req, res) { + res.render('post/editor'); + } + async getComposer (req, res, next) { const { post: postService } = this.dtp.services; try { diff --git a/app/models/post.js b/app/models/post.js index 5af618d..736338f 100644 --- a/app/models/post.js +++ b/app/models/post.js @@ -19,7 +19,8 @@ const POST_STATUS_LIST = ['draft','published','archived']; const PostSchema = new Schema({ created: { type: Date, default: Date.now, required: true, index: -1 }, updated: { type: Date }, - author: { type: Schema.ObjectId, required: true, index: 1, ref: 'User' }, + authorType: { type: String, enum: ['User', 'CoreUser'], required: true }, + author: { type: Schema.ObjectId, required: true, index: 1, refPath: 'authorType' }, image: { type: Schema.ObjectId, ref: 'Image' }, title: { type: String, required: true }, slug: { type: String, required: true, lowercase: true, unique: true }, @@ -33,4 +34,12 @@ const PostSchema = new Schema({ }, }); +PostSchema.index({ + authorType: 1, + author: 1, + status: 1, +}, { + name: 'post_author_by_type', +}); + module.exports = mongoose.model('Post', PostSchema); \ No newline at end of file diff --git a/app/services/post.js b/app/services/post.js index 30c48b2..44b3f59 100644 --- a/app/services/post.js +++ b/app/services/post.js @@ -145,6 +145,7 @@ class PostService extends SiteService { .sort({ created: -1 }) .skip(pagination.skip) .limit(pagination.cpp) + .populate(this.populatePost) .lean(); return posts; } @@ -168,16 +169,22 @@ class PostService extends SiteService { return posts; } - async getAuthorDrafts (author) { - const drafts = await Post + async getForAuthor (author, status, maxCount) { + let q = Post .find({ authorType: author.type, author: author._id, - status: 'draft', + status, }) - .populate(this.populatePost) - .lean(); - return drafts; + .sort({ created: -1 }) + .populate(this.populatePost); + + if (maxCount) { + q = q.limit(maxCount); + } + + const posts = await q.lean(); + return posts; } async getById (postId) { diff --git a/app/services/user.js b/app/services/user.js index 60890b2..f1a06f6 100644 --- a/app/services/user.js +++ b/app/services/user.js @@ -95,8 +95,8 @@ class UserService extends SiteService { user.password = maskedPassword; user.flags = { - isAdmin: false, - isModerator: false, + isAdmin: userDefinition.isAdmin || false, + isModerator: userDefinition.isModerator || false, }; user.permissions = { @@ -104,6 +104,8 @@ class UserService extends SiteService { canChat: true, canComment: true, canReport: true, + canAuthorPosts: userDefinition.canAuthorPosts || false, + canAuthorPages: userDefinition.canAuthorPages || false, }; user.optIn = { diff --git a/app/views/author/index.pug b/app/views/author/index.pug index 2887fce..4b0861b 100644 --- a/app/views/author/index.pug +++ b/app/views/author/index.pug @@ -1,13 +1,54 @@ -extends ../layouts/main-sidebar +extends ../layouts/main block content - h1 Author Dashboard + section.uk-section.uk-section-default + .uk-container + h1 Author Dashboard -block content-sidebar + div(uk-grid) + .uk-width-2-3 + +renderSectionTitle('Recent Comments') - if Array.isArray(drafts) && (drafts.length > 0) - h2 Your Drafts - ul.uk-list - each draft in drafts - li - a(href=`/post/${draft._id}/edit`)= draft.title \ No newline at end of file + .uk-width-1-3 + if Array.isArray(drafts) && (drafts.length > 0) + +renderSectionTitle('Drafts') + ul.uk-list.uk-list-divider + each draft in drafts + li + div(uk-grid).uk-grid-small.uk-flex-middle + .uk-width-expand + a(href=`/post/${draft._id}/edit`, title="Edit draft")= draft.title + .uk-article-meta + div(uk-grid).uk-grid-small.uk-text-small + .uk-width-expand + a(href=`/post/${draft.slug}`, title="Edit draft")= moment(draft.created).fromNow() + + .uk-width-auto + button( + type="button", + title="Delete draft", + data-draft-id= draft._id, + data-draft-title= draft.title, + onclick="return dtp.app.deleteDraft(event);", + ).uk-button.uk-button-danger.uk-button-small + span + i.fas.fa-trash + + if Array.isArray(posts) && (posts.length > 0) + +renderSectionTitle('Posts') + ul.uk-list.uk-list-divider + each post in posts + li + a(href=`/post/${post.slug}`).uk-display-block + div= post.title + .uk-article-meta + div(uk-grid).uk-grid-small.uk-text-small + .uk-width-expand + a(href=`/post/${post.slug}`)= moment(post.created).fromNow() + .uk-width-auto + a(href=`/post/${post._id}/edit`).uk-display-block + +renderButtonIcon('fa-pen', 'edit') + .uk-width-auto + span= formatCount(post.stats.totalVisitCount) + span.uk-margin-small-left + i.fas.fa-eye \ No newline at end of file diff --git a/app/views/components/off-canvas.pug b/app/views/components/off-canvas.pug index d52bba4..46ffe46 100644 --- a/app/views/components/off-canvas.pug +++ b/app/views/components/off-canvas.pug @@ -28,6 +28,15 @@ mixin renderMenuItem (iconClass, label) if user li.uk-nav-header Member Menu + if user.permissions.canAuthorPosts + li(class={ "uk-active": (currentView === 'author') }) + a(href='/author').uk-display-block + div(uk-grid).uk-grid-collapse + .uk-width-auto + .app-menu-icon + i.fas.fa-user + .uk-width-expand Author Dashboard + li(class={ "uk-active": (currentView === 'user-settings') }) a(href=`/user/${user._id}`).uk-display-block div(uk-grid).uk-grid-collapse diff --git a/app/views/index.pug b/app/views/index.pug index a717ce9..541d210 100644 --- a/app/views/index.pug +++ b/app/views/index.pug @@ -23,7 +23,8 @@ block content +renderBlogPostFeaturedItem(post) //- Blog Posts - +renderSectionTitle('Blog Posts') + .uk-margin-large + +renderSectionTitle(`${site.name} Posts`) if Array.isArray(posts) && (posts.length > 0) - var postIndex = 1; diff --git a/app/views/post/components/list-item.pug b/app/views/post/components/list-item.pug index 02bbce8..023cc53 100644 --- a/app/views/post/components/list-item.pug +++ b/app/views/post/components/list-item.pug @@ -18,7 +18,7 @@ mixin renderBlogPostListItem (post, postIndex = 1, postIndexModulus = 3) article.uk-article h4(style="line-height: 1.1;").uk-article-title.uk-margin-small= post.title .uk-article-meta - if post.updated - span updated: #{moment(post.updated).format("MMM DD YYYY HH:MM a")} - else - span published: #{moment(post.created).format("MMM DD YYYY HH:MM a")} \ No newline at end of file + div(uk-grid).uk-grid-small + .uk-width-auto author: #{post.author.displayName || post.author.username} + .uk-width-auto + span published: #{moment(post.created).format("MMM DD YYYY HH:MM a")} \ No newline at end of file diff --git a/app/views/post/editor.pug b/app/views/post/editor.pug index 948d2e5..45e9984 100644 --- a/app/views/post/editor.pug +++ b/app/views/post/editor.pug @@ -38,7 +38,7 @@ block content textarea(id="summary", name="summary", rows="4", placeholder= "Enter post summary (text only, no HTML)").uk-textarea= post ? post.summary : undefined div(uk-grid) .uk-width-auto - button(type="submit").uk-button.dtp-button-primary= post ? 'Update post' : 'Create post' + button(type="submit").uk-button.uk-button-primary= post ? 'Update post' : 'Create post' .uk-margin label(for="status").uk-form-label Status select(id="status", name="status").uk-select diff --git a/app/views/post/view.pug b/app/views/post/view.pug index 337995d..87e8608 100644 --- a/app/views/post/view.pug +++ b/app/views/post/view.pug @@ -15,7 +15,7 @@ block content div #{moment(post.created).format('MMM DD, YYYY, hh:mm a')}, by #[a(href=`/user/${post.author._id}`)= post.author.displayName || post.author.username] if user && user.flags.isAdmin .uk-width-auto - a(href=`/admin/post/${post._id}`) + a(href=`/post/${post._id}/edit`) +renderButtonIcon('fa-pen', 'edit') .uk-width-auto +renderButtonIcon('fa-eye', displayIntegerValue(post.stats.totalViewCount))