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