Author view

Better author dashboard
master
Andrew 1 year ago
parent ab7aa081cc
commit d4839e2d3b

@ -0,0 +1,55 @@
// admin/otp.js
// Copyright (C) 2021 Digital Telepresence, LLC
// License: Apache-2.0
'use strict';
const express = require('express');
// const multer = require('multer');
const { SiteController, SiteError } = require('../../../lib/site-lib');
class OtpAdminController extends SiteController {
constructor (dtp) {
super(dtp, module.exports);
}
async start ( ) {
// const upload = multer({ dest: `/tmp/${this.dtp.config.site.domainKey}/uploads/${module.exports.slug}` });
const router = express.Router();
router.use(async (req, res, next) => {
res.locals.currentView = 'admin';
res.locals.adminView = 'otp';
return next();
});
// router.param('otp', this.populateOtp.bind(this));
router.get('/', this.getIndex.bind(this));
return router;
}
async getIndex (req, res, next) {
try {
const { otpAuth: otpAuthService } = this.dtp.services;
if (!req.user) {
throw new SiteError(402, "Error getting user");
}
res.locals.tokens = await otpAuthService.getBackupTokens(req.user, "Admin");
res.render('admin/otp/index');
} catch (error) {
this.log.error('failed to get tokens', { error });
return next(error);
}
}
}
module.exports = {
name: 'adminOtp',
slug: 'admin-opt',
create: async (dtp) => { return new OtpAdminController(dtp); },
};

@ -0,0 +1,51 @@
mixin renderFileUploadImage (actionUrl, containerId, imageId, imageClass, defaultImage, currentImage, cropperOptions)
div(id= containerId).dtp-file-upload
form(method="POST", action= actionUrl, enctype="multipart/form-data", onsubmit= "return dtp.app.submitImageForm(event);").uk-form
.uk-margin
.uk-card.uk-card-default.uk-card-small
.uk-card-body
div(uk-grid).uk-flex-middle.uk-flex-center
div(class="uk-width-1-1 uk-width-auto@m")
.upload-image-container.size-512
if !!currentImage
img(id= imageId, src= currentImage.path, class= imageClass).sb-large
else
img(id= imageId, src= defaultImage, class= imageClass)
div(class="uk-width-1-1 uk-width-auto@m")
.uk-text-small.uk-margin
#file-select
.uk-margin(class="uk-text-center uk-text-left@m")
span.uk-text-middle Select an image
div(uk-form-custom).uk-margin-small-left
input(
type="file",
formenctype="multipart/form-data",
accept=".jpg,.png,image/jpeg,image/png",
data-file-select-container= containerId,
data-file-select="test-image-upload",
data-file-size-element= "file-size",
data-file-max-size= 15 * 1024000,
data-image-id= imageId,
data-cropper-options= cropperOptions,
onchange="return dtp.app.selectImageFile(event);",
)
button(type="button", tabindex="-1").uk-button.uk-button-default Select
#file-info(class="uk-text-center uk-text-left@m", hidden)
#file-name.uk-text-bold
if currentImage
div resolution: #[span#image-resolution-w= numeral(currentImage.metadata.width).format('0,0')]x#[span#image-resolution-h= numeral(currentImage.metadata.height).format('0,0')]
div size: #[span#file-size= numeral(currentImage.metadata.size).format('0,0.00b')]
div last modified: #[span#file-modified= moment(currentImage.created).format('MMM DD, YYYY')]
else
div resolution: #[span#image-resolution-w 512]x#[span#image-resolution-h 512]
div size: #[span#file-size N/A]
div last modified: #[span#file-modified N/A]
.uk-card-footer
div(class="uk-flex-center", uk-grid)
#file-save-btn(hidden).uk-width-auto
button(
type="submit",
).uk-button.uk-button-primary Save

@ -0,0 +1,28 @@
extends ../layouts/main
block content
div(uk-grid).uk-flex-middle
.uk-width-expand
h1.margin-remove Tokens
section.uk-section.uk-section-default.uk-section-xsmall
.uk-container
.uk-text-small
h4 This is where you will regenerate OTP tokens for your admin account and destroy your old OTP account.
//- .uk-width-auto
button(
type="button",
data-user= user._id,
onclick="return dtp.adminApp.generateOTPTokens(event);",
).uk-button.dtp-button-danger
+renderButtonIcon('fa-repeat', 'Generate OTP Tokens')
//- regenerate route should set this so tokens can be viewed once.
if otpRegen
section.uk-section.uk-section-default.uk-section-xsmall
.uk-container
h3 You should save these tokens in a safe place. This is the only time you will see them.
p These tokens should be saved in a safe place so you can get into your account should you lose your 2FA device
each token of tokens
ul.uk-list.uk-list-divider
li
.uk-text-small= token.token

@ -0,0 +1,47 @@
extends ../layouts/main
block vendorcss
link(rel='stylesheet', href=`/cropperjs/cropper.min.css?v=${pkg.version}`)
block vendorjs
script(src=`/cropperjs/cropper.min.js?v=${pkg.version}`)
block content
include ../components/file-upload-image
//- h2 Add or replace your site images here
div(uk-grid).uk-flex-middle
.uk-width-expand
fieldset
legend Site Icon
.uk-margin
if siteIcon
p.uk-card-title Replace your site icon below.
else
p.uk-card-title You do not currently have a site icon. Add one below.
+renderFileUploadImage(
`/admin/settings/images/updateSiteIcon`,
'site-icon-upload',
'site-icon-file',
'site-icon-picture',
`/img/icon/dtp-sites.png`,
siteIcon,
{ aspectRatio: 1 },
)
div(uk-grid).uk-flex-middle
.uk-width-expand
fieldset
legend Default poster
.uk-margin
if postImage
p.uk-card-title Replace your default post image below.
else
p.uk-card-title You do not currently have a default post image. Add one below.
+renderFileUploadImage(
`/admin/settings/images/updatePostImage`,
'site-post-upload',
'site-post-file',
'site-post-picture',
`/img/default-poster.jpg`,
postImage,
{ aspectRatio: 16/9 },
)

@ -0,0 +1,64 @@
mixin renderPostDraftList (posts)
if Array.isArray(posts) && (posts.length > 0)
ul.uk-list.uk-list-divider
each draft in posts
li
a(href=`/post/${draft.slug}`, title="Preview draft")= draft.title
.uk-article-meta
div(uk-grid).uk-grid-small.uk-flex-middle
.uk-width-expand
.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()
if drafts.all
span by
a(href=`/user/${draft.author.username}`)=` ${draft.author.username}`
.uk-width-auto
a(href=`/post/${draft._id}/edit`).uk-display-block
+renderButtonIcon('fa-pen', 'edit')
.uk-width-auto
a(
href="",
title="Delete draft",
data-post-id= draft._id,
data-post-title= draft.title,
onclick="return dtp.app.deletePost(event);",
).uk-text-danger
+renderButtonIcon('fa-trash', 'delete')
else
.uk-margin-small You have no drafts.
mixin renderFullDraftList (posts)
if Array.isArray(posts) && (posts.length > 0)
ul.uk-list.uk-list-divider
each draft in posts
li
a(href=`/post/${draft.slug}`, title="Preview draft")= draft.title
.uk-article-meta
div(uk-grid).uk-grid-medium.uk-flex-middle
.uk-width-expand
.uk-article-meta
div(uk-grid).uk-grid-medium.uk-text-medium
.uk-width-expand
a(href=`/post/${draft.slug}`, title="Edit draft")= moment(draft.created).fromNow()
if drafts.all
span by
a(href=`/user/${draft.author.username}`)=` ${draft.author.username}`
.uk-width-auto
a(href=`/post/${draft._id}/edit`).uk-display-block
+renderButtonIcon('fa-pen', 'edit')
.uk-width-auto
a(
href="",
title="Delete draft",
data-post-id= draft._id,
data-post-title= draft.title,
onclick="return dtp.app.deletePost(event);",
).uk-text-danger
+renderButtonIcon('fa-trash', 'delete')
+renderPaginationBar('/author/drafts', posts.totalPostCount)
else
.uk-margin-small You have no drafts.

@ -0,0 +1,24 @@
mixin renderBlogPostListItem (post, postIndex = 1, postIndexModulus = 3)
a(href=`/post/${post.slug}`).uk-display-block.uk-link-reset
div(uk-grid).uk-grid-small
div(class="uk-width-1-1 uk-width-1-3@s uk-flex-first", class={
'uk-flex-first@m': ((postIndex % postIndexModulus) === 0),
'uk-flex-last@m': ((postIndex % postIndexModulus) !== 0),
})
if post.image
img(src= `/image/${post.image._id}`).responsive
else
img(src="/img/default-poster.jpg").responsive
div(class='uk-width-1-1 uk-width-2-3@s', class="uk-flex-last", class={
'uk-flex-first@m': ((postIndex % postIndexModulus) !== 0),
'uk-flex-last@m': ((postIndex % postIndexModulus) === 0),
})
article.uk-article
h4(style="line-height: 1.1;").uk-article-title.uk-margin-small= post.title
.uk-article-meta
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")}

@ -0,0 +1,70 @@
mixin renderPostList (posts)
if Array.isArray(posts) && (posts.length > 0)
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()
if posts.all
span by
a(href=`/user/${post.author.username}`)=` ${post.author.username}`
.uk-width-auto
a(href=`/post/${post._id}/edit`).uk-display-block
+renderButtonIcon('fa-pen', 'edit')
.uk-width-auto
a(
href="",
data-post-id= post._id,
data-post-title= post.title,
onclick="return dtp.app.deletePost(event);",
).uk-display-block.uk-text-danger
+renderButtonIcon('fa-trash', 'delete')
div(style="width: 65px;")
span
i.fas.fa-eye
span.uk-margin-small-left= formatCount(post.stats.totalVisitCount)
else
.uk-margin-small There are no posts.
mixin renderPublishedPostList (posts)
if Array.isArray(posts) && (posts.length > 0)
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()
if posts.all
span by
a(href=`/user/${post.author.username}`)=` ${post.author.username}`
.uk-width-auto
a(href=`/post/${post._id}/edit`).uk-display-block
+renderButtonIcon('fa-pen', 'edit')
.uk-width-auto
a(
href="",
data-post-id= post._id,
data-post-title= post.title,
onclick="return dtp.app.deletePost(event);",
).uk-display-block.uk-text-danger
+renderButtonIcon('fa-trash', 'delete')
div(style="width: 65px;")
span
i.fas.fa-eye
span.uk-margin-small-left= formatCount(post.stats.totalVisitCount)
+renderPaginationBar('/author/posts', posts.totalPostCount)
else
.uk-margin-small No published posts.

@ -0,0 +1,28 @@
extends ../../layouts/main
block content
include ../components/draft-list
include ../components/list
include ../../post/components/summary
include ../../components/pagination-bar
section.uk-section.uk-section-default.uk-section-xsmall
.uk-container.uk-container-expand
div(uk-grid).uk-flex-middle
.uk-width-expand
h2.uk-margin-remove Drafts
.uk-width-auto
if user.permissions.canAuthorPosts || user.flags.isAdmin
a(href= "/post/compose").uk-button.uk-button-primary.uk-border-rounded
span
i.fas.fa-plus
span.uk-margin-small-left.uk-text-bold Create Post
.uk-width-medium
a(href= "/author").uk-button.uk-button-primary.uk-border-rounded
span.uk-margin-small-middle.uk-text-bold Author Dashboard
div(uk-grid)
div(class="uk-width-1-1 uk-width-3-3@m")
+renderSectionTitle('Drafts')
+renderFullDraftList(drafts.posts)

@ -5,7 +5,18 @@ block content
.uk-container
h1 2FA Setup Successful
section.uk-section.uk-section-default.uk-section-xsmall
.uk-container
h3 You should save these tokens in a safe place. This is the only time you will see them.
p These tokens should be saved in a safe place so you can get into your account should you lose your 2FA device
each token of otpAccount.backupTokens
ul.uk-list.uk-list-divider
li
.uk-text-small= token.token
section.uk-section.uk-section-default.uk-section-xsmall
.uk-container
p Your account is now enabled with access to #{site.name} #{otpServiceName}.
a(href= otpRedirectURL, title="Continue").uk-button.uk-button-primary.uk-border-pill Continue
p Your account is now enabled with access to #{site.name} #{otpAccount.service}.
a(href= otpRedirectURL, title="Continue").uk-button.uk-button-primary.uk-border-pill Continue

@ -0,0 +1,16 @@
extends ../../layouts/main-sidebar
block content
include ../../components/pagination-bar
include components/credit
div(uk-grid).uk-flex-expand
.uk-width-expand
h3.uk-margin-remove= `Author List`
if Array.isArray(authors) && (authors.length > 0)
ul.uk-list.uk-list-divider
each author in authors
li
+renderAuthorCredit(author)
.uk-card-footer
+renderPaginationBar(`/post/authors`, totalAuthorCount )

@ -0,0 +1,42 @@
mixin renderAuthorCredit (author)
div(uk-grid).uk-grid-small
.uk-width-auto
+renderProfileIcon(author)
.uk-width-expand
.uk-margin-small
div(uk-grid).uk-flex-middle
.uk-width-expand
- var userUrl = !!author.coreUserId ? `/user/core/${author._id}` : `/user/${author.username}`;
a(href= userUrl, title="View member profile")
.uk-text-bold(style="line-height: 1em;")= author.displayName || author.username
.uk-width-auto
.uk-text-small.uk-text-muted(style="line-height: 1em;")
if author.coreUserId
a(href=`${process.env.DTP_CORE_AUTH_SCHEME}://${author.core.meta.domain}/user/${author.coreUserId}`)= author.core.meta.name
else if !Array.isArray(posts)
a(href= `/post/author/${author.username}`)= `View posts by author`
.uk-text-small= author.bio
mixin renderUserIcon (user, title, size = "small")
if user.coreUserId
img(
src=`http://${user.core.meta.domain}/core/user/${user.coreUserId}/picture?s=${sizeMap[size]}`,
class= "site-profile-picture",
class= `sb-${size}`,
title= title,
)
else
if user.picture && user.picture.small
img(
src= `/image/${user.picture[sizeMap[size]]._id}`,
class= "site-profile-picture",
class= `sb-${size}`,
title= title,
)
else
img(
src= "/img/default-member.png",
class= "site-profile-picture",
class= `sb-${size}`,
title= title,
)

@ -0,0 +1,15 @@
mixin renderPostSummaryFull (post)
div(uk-grid).uk-grid-small
if post.image
.uk-width-auto
img(src= `/image/${post.image._id}`).uk-width-small
else
.uk-width-auto
img(src="/img/default-poster.jpg").uk-width-small
.uk-width-expand
.uk-text-large.uk-text-bold(style="line-height: 1em;")
a(href=`/post/${post.slug}`)= `${post.title}`
.uk-text-small.uk-text-muted
div
div= moment(post.created).fromNow()
div= post.summary

@ -0,0 +1,34 @@
extends ../../layouts/main
block content
include ../../components/pagination-bar
include components/list
include components/credit
section(class="uk-section uk-section-default uk-section-small")
div(class="uk-container uk-container-expand")
div(class="uk-margin-medium")
h2= `Author page for ${author.username}`
div(class="uk-margin")
div(class="uk-grid").uk-grid
div(class="uk-width-1-1 uk-width-1-4@m uk-first-column")
+renderUserIcon(author, author.displayName || author.username, 'large')
.uk-margin
.uk-card.uk-card-default.uk-card-small
.uk-card-header.uk-text-center
h1.uk-card-title Bio
div(class="uk-card uk-card-default uk-card-body")
p= author.bio
div(class="uk-width-1-1 uk-width-expand@m")
div.uk-container
h3.uk-margin-medium= `Posts`
if Array.isArray(posts) && (posts.length > 0)
ul.uk-list.uk-list-divider
each post in posts
li
+renderPostSummaryFull(post)
.uk-card-footer
+renderPaginationBar(`/post/author/${author.username}`, posts.totalPostCount )

@ -0,0 +1,19 @@
mixin renderPostSummaryFull (post)
div(uk-grid).uk-grid-small
if post.image
.uk-width-auto
img(src= `/image/${post.image._id}`).uk-width-medium
else
.uk-width-auto
img(src="/img/default-poster.jpg").uk-width-medium
.uk-width-expand
.uk-text-large.uk-text-bold(style="line-height: 1em;")
a(href=`/post/${post.slug}`)= `${post.title}`
.uk-text-small.uk-text-muted
div
div= moment(post.created).fromNow()
span by
a(href=`/user/${post.author.username}`)=` ${post.author.username}`
if user && allPosts
div= `Status: ${post.status}`
div= post.summary

@ -0,0 +1,37 @@
extends ../../layouts/main-sidebar
include components/list
include ../../components/pagination-bar
block content
if Array.isArray(posts) && (posts.length > 0)
h3= `Posts with the tag ${tag}.`
ul.uk-list.uk-list-divider
each post in posts
li
+renderPostSummaryFull(post)
.uk-card-footer
+renderPaginationBar(`/post/tag/${tagSlug}`, posts.total )
//- li
if post.image
img(src= `/image/${post.image._id}`, href=`/post/${post.slug}`, style="max-height: 350px; object-fit: cover; vertical-align:middle;margin:0px 20px;").responsive
else
img(src="/img/default-poster.jpg", href=`/post/${post.slug}`, style="max-height: 350px; object-fit: cover; vertical-align:middle;margin:0px 20px;").responsive
a(href=`/post/${post.slug}`).uk-display-block
div.h2= 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()
span by
a(href=`/user/${post.author.username}`)=` ${post.author.username}`
.uk-width-expand
div= post.summary
else
h3= `There are no posts with the tag ${tag}.`
Loading…
Cancel
Save