completed categories feature
This commit is contained in:
parent
03f01f65d3
commit
9f2b80a924
@ -3,7 +3,7 @@ import mongoose from 'mongoose';
|
||||
const { Schema } = mongoose;
|
||||
const CategorySchema = new Schema({
|
||||
name: { type: String, required: true, index: { unique: true } },
|
||||
slug: { type: String, required: true, index: { unique: true } }
|
||||
slug: { type: String, index: { unique: true } }
|
||||
});
|
||||
|
||||
|
||||
|
@ -4,11 +4,11 @@ import Category from '../../models/category.js';
|
||||
export async function get(req, res)
|
||||
{
|
||||
let { slug } = req.params;
|
||||
let articles;
|
||||
let articles, cat;
|
||||
if (slug === 'all') {
|
||||
articles = await Article.find().sort({ created_at: 'desc' });
|
||||
articles = await Article.find().sort({ created_at: 'desc' }).populate({ path: 'category' });
|
||||
} else {
|
||||
let cat = await Category.findOne({ slug });
|
||||
cat = await Category.findOne({ slug });
|
||||
if (!cat) {
|
||||
res.writeHead(404, {
|
||||
'Content-Type': 'application/json'
|
||||
@ -18,11 +18,13 @@ export async function get(req, res)
|
||||
}));
|
||||
return;
|
||||
} else {
|
||||
articles = await Article.find({ category: cat.id }).sort({ created_at: 'desc' });
|
||||
articles = await Article.find({ category: cat.id })
|
||||
.sort({ created_at: 'desc' })
|
||||
.populate({ path: 'category' });
|
||||
}
|
||||
}
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
res.end(JSON.stringify(articles));
|
||||
res.end(JSON.stringify({ category: cat, articles }));
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
<script context="module">
|
||||
export async function preload({ params, query }) {
|
||||
if (params.slug === 'all') {
|
||||
this.redirect(302, '/');
|
||||
}
|
||||
const res = await this.fetch(`c/${params.slug}.json`);
|
||||
const data = await res.json();
|
||||
|
||||
if (res.status === 200) {
|
||||
return {
|
||||
articles: data.articles,
|
||||
category: data.category
|
||||
};
|
||||
} else {
|
||||
this.error(res.status, data.message);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{category.name} Articles | HOWFEED.BIZ</title>
|
||||
</svelte:head>
|
||||
|
||||
<style>
|
||||
h1 {
|
||||
margin: 0 auto;
|
||||
color: whitesmoke;
|
||||
margin-top: 1rem;
|
||||
font-size: 2rem;
|
||||
font-size: 3rem;
|
||||
text-transform: uppercase;
|
||||
text-align: center;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
h1 {
|
||||
font-size: 4rem !important;
|
||||
}
|
||||
}
|
||||
@media (min-width: 1280px) {
|
||||
h1 {
|
||||
font-size: 8rem !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
export let articles;
|
||||
export let category;
|
||||
</script>
|
||||
|
||||
<div class="background"></div>
|
||||
<div class="floaty">
|
||||
<h1>{category.name}</h1>
|
||||
<div class="article-list">
|
||||
{#each articles as {title, slug, image, created_at}}
|
||||
<a rel="prefetch" href={`/a/${slug}`}>
|
||||
<figure class="article-image">
|
||||
<img src={image || '/logo.png'} alt={title}>
|
||||
</figure>
|
||||
<div class="article-meta">
|
||||
<p class="article-title">{title}</p>
|
||||
<p class="article-date">{new Date(created_at).toLocaleDateString()}</p>
|
||||
</div>
|
||||
</a>
|
||||
{:else}
|
||||
<p>No articles are in this category :(</p>
|
||||
<p>Check back soon!</p>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
@ -70,7 +70,7 @@
|
||||
'Accept': 'application/json',
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({ html, image, title })
|
||||
body: JSON.stringify({ html, image, title, category })
|
||||
});
|
||||
const json = await res.json();
|
||||
goto(`/a/${json.slug}`);
|
||||
@ -89,6 +89,7 @@
|
||||
body: JSON.stringify({ name })
|
||||
});
|
||||
categories = await res.json();
|
||||
category = categories.filter(c => c.name === name)[0].slug;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -2,7 +2,7 @@
|
||||
export async function preload()
|
||||
{
|
||||
const res = await this.fetch(`/c/all.json`);
|
||||
const articles = await res.json();
|
||||
const { articles } = await res.json();
|
||||
return { articles };
|
||||
}
|
||||
</script>
|
||||
@ -19,22 +19,7 @@
|
||||
h1, h2, p {
|
||||
margin: 0 auto;
|
||||
}
|
||||
h1 {
|
||||
font-size: 3rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
figure {
|
||||
margin: 0;
|
||||
}
|
||||
img {
|
||||
object-fit: contain;
|
||||
max-width: 100%;
|
||||
margin: 1rem;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
div.homepage {
|
||||
padding-top: 5rem !important;
|
||||
}
|
||||
h1.welcome {
|
||||
font-size: 8rem !important;
|
||||
}
|
||||
@ -50,42 +35,19 @@
|
||||
font-size: 3.5rem !important;
|
||||
}
|
||||
}
|
||||
div.background {
|
||||
background: url('/cityscape.jpg') no-repeat center;
|
||||
background-size: cover;
|
||||
position: fixed;
|
||||
height: 24rem;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
filter: blur(5px);
|
||||
}
|
||||
div.homepage {
|
||||
padding-top: 8rem;
|
||||
padding-bottom: 4rem;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
h1.welcome, h2.desc {
|
||||
color: whitesmoke;
|
||||
}
|
||||
h1.welcome {
|
||||
margin-top: 1rem;
|
||||
font-size: 3.75rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 3rem;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
h2.desc {
|
||||
margin-bottom: 1rem;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
div.article-list {
|
||||
box-shadow: 0 0 5px #000;
|
||||
}
|
||||
div.article-meta {
|
||||
font-weight: bold;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -94,7 +56,7 @@
|
||||
</svelte:head>
|
||||
|
||||
<div class="background"></div>
|
||||
<div class="homepage">
|
||||
<div class="floaty">
|
||||
<h1 class="welcome">Welcome</h1>
|
||||
<h2 class="desc">Find an Article</h2>
|
||||
<div class="article-list">
|
||||
@ -110,7 +72,7 @@
|
||||
</a>
|
||||
{:else}
|
||||
<p>No articles have been published yet :(</p>
|
||||
<p>Come back soon!</p>
|
||||
<p>Chcek back soon!</p>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -257,10 +257,10 @@ express()
|
||||
}
|
||||
const cat = await new Category({ name });
|
||||
await cat.save();
|
||||
const categories = await Category.find();
|
||||
res.writeHead(200, {
|
||||
'Content-Type': 'application/json'
|
||||
});
|
||||
const categories = await Category.find();
|
||||
res.end(JSON.stringify(categories));
|
||||
} catch (err) {
|
||||
res.writeHead(500, {
|
||||
|
@ -80,10 +80,14 @@ figure.article-image {
|
||||
align-self: center;
|
||||
justify-content: center;
|
||||
width: 33.33%;
|
||||
margin: 0;
|
||||
}
|
||||
figure.article-image img {
|
||||
height: 6rem;
|
||||
width: auto;
|
||||
object-fit: contain;
|
||||
max-width: 100%;
|
||||
margin: 1rem;
|
||||
}
|
||||
div.article-meta {
|
||||
margin: 1rem;
|
||||
@ -95,9 +99,11 @@ div.article-meta {
|
||||
}
|
||||
.article-title {
|
||||
font-size: 2rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.article-date {
|
||||
font-size: 1rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.content {
|
||||
@ -105,3 +111,34 @@ div.article-meta {
|
||||
margin: 8rem 0;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
div.background {
|
||||
background: url('/cityscape.jpg') no-repeat center;
|
||||
background-size: cover;
|
||||
position: fixed;
|
||||
height: 24rem;
|
||||
width: 100%;
|
||||
z-index: 0;
|
||||
filter: blur(5px);
|
||||
}
|
||||
|
||||
div.article-list {
|
||||
box-shadow: 0 0 5px #000;
|
||||
}
|
||||
div.article-meta {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.floaty {
|
||||
padding-top: 8rem;
|
||||
padding-bottom: 4rem;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
}
|
||||
@media (min-width: 800px) {
|
||||
div.floaty {
|
||||
padding-top: 5rem !important;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user