deleting, view count, realname for articles

This commit is contained in:
James Shiffer 2020-06-12 02:11:53 -07:00
parent 80b8a28c36
commit c0214eef58
6 changed files with 75 additions and 32 deletions

View File

@ -22,21 +22,8 @@ const ArticleSchema = new Schema({
});
ArticleSchema.virtual('author_user', {
ref: 'User',
localField: 'author',
foreignField: '_id',
justOne: true
});
ArticleSchema.methods.genSlug = title => title.toLowerCase().replace(/\W+/g, '-');
ArticleSchema.pre('findOne', function (next) {
var article = this;
article.views++;
next();
});
ArticleSchema.pre('save', function (next) {
var article = this;
// only gen the slug if title has been modified (or is new)

View File

@ -1,3 +1,11 @@
<script context="module">
export async function preload({ user }, page)
{
const res = await this.fetch(`/me`);
user = await res.json();
}
</script>
<script>
import Footer from '../components/Footer.svelte';
import Nav from '../components/Nav.svelte';
@ -5,20 +13,9 @@
<style>
main {
max-width: 100vw;
max-width: 100%;
box-sizing: border-box;
}
footer {
box-sizing: border-box;
text-align: center;
position: fixed;
bottom: 0;
width: 100%;
background: #fff;
box-shadow: 0 2px 5px #000;
padding: 1rem;
z-index: 1;
}
</style>
<Nav />

View File

@ -4,9 +4,14 @@ export async function get(req, res, next) {
// the `slug` parameter is available because
// this file is called [slug].json.js
const { slug } = req.params;
const article = await Article.findOne({ slug }).populate('author_user');
const article = await Article.findOne({ slug }).populate({
path: 'author',
select: 'realname'
});
if (article) {
article.set({ views: article.views + 1 });
article.save();
res.writeHead(200, {
'Content-Type': 'application/json'
});
@ -20,3 +25,20 @@ export async function get(req, res, next) {
}));
}
}
export async function del(req, res, next) {
const { slug } = req.params;
const article = await Article.findOneAndDelete({ slug });
if (article) {
res.writeHead(204);
res.end();
} else {
res.writeHead(404, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `Not found`
}));
}
}

View File

@ -64,9 +64,13 @@
}
div.article-meta {
margin: 0;
margin: 0 0 4rem 0;
padding: 0;
}
div.article-meta h1 {
margin-bottom: 0;
}
</style>
<svelte:head>
@ -79,6 +83,9 @@
</figure>
<div class="article-meta">
<h1 class="article-title">{article.title}</h1>
<p>Author: <strong>{article.author.realname}</strong></p>
<p>Published: <strong>{new Date(article.created_at).toLocaleString()}</strong></p>
<p>Views: <strong>{article.views}</strong></p>
</div>
{@html article.html}
</div>

View File

@ -15,12 +15,17 @@
</svelte:head>
<script>
import { goto } from '@sapper/app';
export let articles;
function del(article)
async function del(article)
{
if (confirm(`Are you sure you want to delete "${article.title}"?`)) {
alert('ok');
await fetch(`/a/${article.slug}.json`, {
method: 'DELETE'
});
const res = await fetch(`/a/all`);
articles = await res.json();
}
}
</script>
@ -31,7 +36,8 @@
<ul>
{#each articles as article}
<li>
<strong>{article.title}</strong> by <strong>{article.author_user}</strong>
<strong>{article.title}</strong> by <strong>{article.author.realname}</strong>
({article.views} views)
<button on:click={() => { del(article) }}>Delete</button>
</li>
{:else}

View File

@ -212,7 +212,12 @@ express()
}
const article = await new Article({ html, title, image, author: req.user._id });
await article.save();
res.redirect(`/a/${article.slug}`);
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
slug: article.slug
}));
} catch (err) {
res.writeHead(500, {
'Content-Type': 'application/json'
@ -225,7 +230,10 @@ express()
)
.get('/a/all', async function (req, res, next) {
let articles = await Article.find().populate('author_user');
let articles = await Article.find().sort({ created_at: 'desc' }).populate({
path: 'author',
select: 'realname'
});
articles.forEach(article => {
article.slug = article.title.toLowerCase().replace(/\W+/g, '-');
article.html = article.html.replace(/^\t{3}/gm, '');
@ -236,6 +244,22 @@ express()
res.end(JSON.stringify(articles));
})
.get('/me', function(req, res, next) {
if (req.user) {
res.writeHead(200, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify(req.user));
} else {
res.writeHead(401, {
'Content-Type': 'application/json'
});
res.end(JSON.stringify({
message: `You are not logged in`
}));
}
})
.use(compression({ threshold: 0 }))
.use(sirv('static', { dev }))
.use(sapper.middleware({