Further changes
This commit is contained in:
parent
bff88838d3
commit
f0d042910e
19
src/lib/card-collections/cards/EmptyCard.svelte
Normal file
19
src/lib/card-collections/cards/EmptyCard.svelte
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<div class="card-container">
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.card-container {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: baseline;
|
||||||
|
row-gap: 15px;
|
||||||
|
background-color: var(--overlay-color);
|
||||||
|
width: 90%;
|
||||||
|
height: auto;
|
||||||
|
margin: auto;
|
||||||
|
padding: 10px 5px 10px 5px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
7
src/lib/card-collections/cards/PostCard.svelte
Normal file
7
src/lib/card-collections/cards/PostCard.svelte
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
import EmptyCard from "./EmptyCard.svelte";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<EmptyCard>
|
||||||
|
|
||||||
|
</EmptyCard>
|
7
src/lib/card-collections/cards/ProjectCard.svelte
Normal file
7
src/lib/card-collections/cards/ProjectCard.svelte
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<script>
|
||||||
|
import EmptyCard from "./EmptyCard.svelte";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<EmptyCard>
|
||||||
|
|
||||||
|
</EmptyCard>
|
31
src/lib/card-collections/cards/TagsCard.svelte
Normal file
31
src/lib/card-collections/cards/TagsCard.svelte
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import PostTag from '$lib/posts/PostTag.svelte';
|
||||||
|
import EmptyCard from './EmptyCard.svelte';
|
||||||
|
|
||||||
|
async function fetchTags() {
|
||||||
|
const tags: string[] = [];
|
||||||
|
const endpoint = '/posts/tag/all';
|
||||||
|
const res = await fetch(endpoint);
|
||||||
|
const json = await res.json();
|
||||||
|
if (Array.isArray(json)) {
|
||||||
|
for (const item of json) {
|
||||||
|
tags.push(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tags;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<EmptyCard>
|
||||||
|
{#await fetchTags()}
|
||||||
|
<p>Loading Tags...</p>
|
||||||
|
{:then tags}
|
||||||
|
{#each tags as tag}
|
||||||
|
<div class="tag-link">
|
||||||
|
<PostTag {tag} />
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
{:catch}
|
||||||
|
<p>Unable to load tags</p>
|
||||||
|
{/await}
|
||||||
|
</EmptyCard>
|
@ -1,8 +1,11 @@
|
|||||||
:root {
|
:root {
|
||||||
--main-bg-color: lightslategrey;
|
--main-bg-color: lightslategrey;
|
||||||
--accent-color: darkslategrey;
|
--accent-color: rgb(234, 255, 97);
|
||||||
|
--accent-rollover: yellow;
|
||||||
--overlay-color: #2f4f4fb8;
|
--overlay-color: #2f4f4fb8;
|
||||||
--main-text-color: azure;
|
--main-text-color: azure;
|
||||||
|
--light-text-color: azure;
|
||||||
|
--dark-text-color: rgb(56, 56, 7);
|
||||||
--link-color: cyan;
|
--link-color: cyan;
|
||||||
--link-visited-color: rgb(189, 0, 189);
|
--link-visited-color: rgb(189, 0, 189);
|
||||||
}
|
}
|
||||||
@ -16,6 +19,15 @@
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: 'caprasimo';
|
||||||
|
src: url('/font/caprasimo-regular.woff2') format('woff2'),
|
||||||
|
url('/font/caprasimo-regular.woff') format('woff'),
|
||||||
|
url('/font/caprasimo-regular.ttf') format('truetype');
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
background-color: var(--main-bg-color);
|
background-color: var(--main-bg-color);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -13,13 +13,19 @@
|
|||||||
<style>
|
<style>
|
||||||
header {
|
header {
|
||||||
font-family: shadowsintolight;
|
font-family: shadowsintolight;
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: bolder;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
|
padding-bottom: 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
background-color: var(--accent-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
margin-bottom: 0px;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
padding-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
|
@ -36,29 +36,31 @@
|
|||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 30px;
|
height: 42px;
|
||||||
background-color: transparent;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
background-color: var(--accent-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
nav a {
|
nav a {
|
||||||
float: left;
|
float: left;
|
||||||
display: block;
|
display: block;
|
||||||
color: rgb(46, 46, 46);
|
color: var(--dark-text-color);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
margin-right: 1px;
|
margin-right: 1px;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
font-family: shadowsintolight;
|
font-family: caprasimo;
|
||||||
font-weight: bolder;
|
font-weight: bolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav a:hover {
|
nav a:hover {
|
||||||
background-color: slategray;
|
background-color: var(--main-bg-color);
|
||||||
color: white;
|
color: var(--light-text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
nav a:active {
|
nav a:active {
|
||||||
color: slategray;
|
color: var(--main-bg-color);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
23
src/lib/posts/PostTag.svelte
Normal file
23
src/lib/posts/PostTag.svelte
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let tag: string;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<a class="tag-link" href="/posts/tag/{tag}">
|
||||||
|
{tag}
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.tag-link {
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--dark-text-color);
|
||||||
|
padding: 3px 5px 3px 5px;
|
||||||
|
margin: 10px;
|
||||||
|
background-color: var(--accent-color);
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-link:hover,
|
||||||
|
.tag-link:active {
|
||||||
|
background-color: var(--accent-rollover);
|
||||||
|
}
|
||||||
|
</style>
|
@ -3,19 +3,18 @@
|
|||||||
import Header from '$lib/header.svelte';
|
import Header from '$lib/header.svelte';
|
||||||
import Emphasis from '$lib/highlights/emphasis.svelte';
|
import Emphasis from '$lib/highlights/emphasis.svelte';
|
||||||
import LatestPosts from '$lib/posts/PostsSummary.svelte';
|
import LatestPosts from '$lib/posts/PostsSummary.svelte';
|
||||||
|
import TagsCard from '$lib/card-collections/cards/TagsCard.svelte';
|
||||||
|
|
||||||
const title: string = "Hi, I'm Fred";
|
const title: string = "Hi, I'm Fred";
|
||||||
const subtitle: string = 'Crafting Digital';
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Header {title} {subtitle} />
|
<Header {title} />
|
||||||
<section id="welcome">
|
<section id="welcome">
|
||||||
<div id="header-text">
|
<div id="header-text">
|
||||||
<div id="text-content">
|
<div id="text-content">
|
||||||
<p>
|
<p>
|
||||||
Alongside the railway's iron path, I earn my living and fuel my passions. By day, I'm woven
|
Alongside the railway's iron path, I earn my living and fuel my passions. By day, I'm woven
|
||||||
into the rail's story. By night, I craft, design and build tools that work for people. My
|
into the rail's story. By night, I craft, design and build tools that work for people.
|
||||||
canvas? The web, and beyond.
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
With a family close to heart, I capture life's moments through photography and dabble in
|
With a family close to heart, I capture life's moments through photography and dabble in
|
||||||
@ -41,6 +40,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="tags" class="col">
|
<div id="tags" class="col">
|
||||||
<h1>Tags</h1>
|
<h1>Tags</h1>
|
||||||
|
<TagsCard />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -138,10 +138,14 @@
|
|||||||
#meta-links {
|
#meta-links {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: start;
|
||||||
}
|
}
|
||||||
.col {
|
.col {
|
||||||
width: 30%;
|
width: 30%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-family: caprasimo;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { mongoConnect } from '$lib/database/mongo';
|
import { mongoConnect } from '$lib/database/mongo.server';
|
||||||
import { marked } from 'marked';
|
import { marked } from 'marked';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
import sanitizeHtml from 'sanitize-html';
|
import sanitizeHtml from 'sanitize-html';
|
||||||
@ -44,14 +44,14 @@ export async function load({ params }) {
|
|||||||
|
|
||||||
function renderMarkdown(md: string, renderer: _Renderer): string {
|
function renderMarkdown(md: string, renderer: _Renderer): string {
|
||||||
const rawHtml = marked(md, { renderer });
|
const rawHtml = marked(md, { renderer });
|
||||||
console.log(rawHtml)
|
console.log(rawHtml);
|
||||||
const sanitizedHtml = sanitizeHtml(rawHtml, {
|
const sanitizedHtml = sanitizeHtml(rawHtml, {
|
||||||
allowedTags: ['a', 'br', 'code', 'figcaption', 'figure', 'img', 'p', 'pre'],
|
allowedTags: ['a', 'br', 'code', 'figcaption', 'figure', 'img', 'p', 'pre'],
|
||||||
allowedAttributes: {
|
allowedAttributes: {
|
||||||
'a': ['href'],
|
a: ['href'],
|
||||||
'img': ['alt', 'class', 'src', 'title']
|
img: ['alt', 'class', 'src', 'title']
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log(sanitizedHtml)
|
console.log(sanitizedHtml);
|
||||||
return sanitizedHtml
|
return sanitizedHtml;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Header from '$lib/header.svelte';
|
import Header from '$lib/header.svelte';
|
||||||
|
import PostTag from '$lib/posts/PostTag.svelte';
|
||||||
import type { Article } from '$lib/posts/types';
|
import type { Article } from '$lib/posts/types';
|
||||||
import { afterUpdate } from 'svelte';
|
import { afterUpdate } from 'svelte';
|
||||||
|
|
||||||
@ -38,23 +39,23 @@
|
|||||||
<Header title={post.title} />
|
<Header title={post.title} />
|
||||||
|
|
||||||
<div class="column-container">
|
<div class="column-container">
|
||||||
<div class="main-column">
|
<div class="main-column">
|
||||||
<article>
|
<article>
|
||||||
<p>
|
<p>
|
||||||
{#each post.tags as tag}
|
{#each post.tags as tag}
|
||||||
<span>{tag}</span>
|
<PostTag {tag} />
|
||||||
{/each}<br />
|
{/each}<br /><br />
|
||||||
{post.date.toLocaleDateString()}<br />
|
Published: {post.date.toLocaleDateString()}<br />
|
||||||
Written by: {post.author}
|
Author: {post.author}
|
||||||
</p>
|
</p>
|
||||||
<content>
|
<content>
|
||||||
{@html post.content}
|
{@html post.content}
|
||||||
</content>
|
</content>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
<div class="side-column">
|
<div class="side-column">
|
||||||
<p>HELLO FROM COLUMN 2</p>
|
<p>HELLO FROM COLUMN 2</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -65,16 +66,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
.column-container {
|
.column-container {
|
||||||
flex-direction: row; /* Switch to row layout for larger screens */
|
flex-direction: row; /* Switch to row layout for larger screens */
|
||||||
}
|
}
|
||||||
.main-column {
|
.main-column {
|
||||||
flex: 2; /* Take up 2/3 of the available width */
|
flex: 2; /* Take up 2/3 of the available width */
|
||||||
}
|
}
|
||||||
.side-column {
|
.side-column {
|
||||||
flex: 1; /* Take up 1/3 of the available width */
|
flex: 1; /* Take up 1/3 of the available width */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { mongoConnect } from '$lib/database/mongo';
|
import { mongoConnect } from '$lib/database/mongo.server';
|
||||||
|
|
||||||
export async function load({ params }) {
|
export async function load({ params }) {
|
||||||
const tag = params.tag;
|
const tag = params.tag;
|
||||||
@ -12,5 +12,5 @@ export async function load({ params }) {
|
|||||||
const res = col.find(query);
|
const res = col.find(query);
|
||||||
const posts = await res.toArray();
|
const posts = await res.toArray();
|
||||||
|
|
||||||
return { data: JSON.stringify(posts) };
|
return { data: JSON.stringify(posts), tag: tag };
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import Header from '$lib/header.svelte';
|
||||||
import PostsSummary from '$lib/posts/PostsSummary.svelte';
|
import PostsSummary from '$lib/posts/PostsSummary.svelte';
|
||||||
import type { ArticleSummary } from '$lib/posts/types.js';
|
import type { ArticleSummary } from '$lib/posts/types.js';
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
const posts: ArticleSummary[] = JSON.parse(data.data);
|
const posts: ArticleSummary[] = JSON.parse(data.data);
|
||||||
|
|
||||||
console.log('Posts:', posts);
|
const title = `tag: ${data.tag}`;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h1>Testing</h1>
|
<Header {title} />
|
||||||
|
|
||||||
{#each posts as article}
|
{#each posts as article}
|
||||||
<PostsSummary {article} />
|
<PostsSummary {article} />
|
||||||
|
16
src/routes/posts/tag/all/+server.ts
Normal file
16
src/routes/posts/tag/all/+server.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Fetches all tags and returns a JSON Array of the tags ordered in their frequency of use
|
||||||
|
|
||||||
|
import { error } from '@sveltejs/kit';
|
||||||
|
import type { RequestHandler } from '@sveltejs/kit';
|
||||||
|
import { json } from '@sveltejs/kit';
|
||||||
|
|
||||||
|
import { mongoConnect } from '$lib/database/mongo.server';
|
||||||
|
|
||||||
|
export async function GET({ url }) {
|
||||||
|
const db = await mongoConnect();
|
||||||
|
const col = db.db('fredboniface').collection('posts');
|
||||||
|
// Fetch all possible array values for 'tags' and creata a local `tags` array to return
|
||||||
|
// For now, a static array is used.
|
||||||
|
const tags = ['svelte', 'sveltekit', 'misc', 'model-rail', 'typescript', 'waffle'];
|
||||||
|
return json(tags);
|
||||||
|
}
|
BIN
static/font/caprasimo-regular.ttf
Normal file
BIN
static/font/caprasimo-regular.ttf
Normal file
Binary file not shown.
BIN
static/font/caprasimo-regular.woff
Normal file
BIN
static/font/caprasimo-regular.woff
Normal file
Binary file not shown.
BIN
static/font/caprasimo-regular.woff2
Normal file
BIN
static/font/caprasimo-regular.woff2
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user