mirror of
https://github.com/youwen5/site.git
synced 2024-11-24 17:33:51 -08:00
feat: add metadata display to blog posts
This commit is contained in:
parent
13069c4e2a
commit
bd53c89296
4 changed files with 61 additions and 2 deletions
|
@ -50,6 +50,7 @@
|
||||||
"@sveltejs/adapter-vercel": "^5.2.0",
|
"@sveltejs/adapter-vercel": "^5.2.0",
|
||||||
"bits-ui": "^0.21.2",
|
"bits-ui": "^0.21.2",
|
||||||
"clsx": "^2.1.0",
|
"clsx": "^2.1.0",
|
||||||
|
"dayjs": "^1.11.10",
|
||||||
"marked": "^12.0.1",
|
"marked": "^12.0.1",
|
||||||
"marked-alert": "^2.0.1",
|
"marked-alert": "^2.0.1",
|
||||||
"marked-katex-extension": "^5.0.1",
|
"marked-katex-extension": "^5.0.1",
|
||||||
|
|
|
@ -26,6 +26,9 @@ dependencies:
|
||||||
clsx:
|
clsx:
|
||||||
specifier: ^2.1.0
|
specifier: ^2.1.0
|
||||||
version: 2.1.0
|
version: 2.1.0
|
||||||
|
dayjs:
|
||||||
|
specifier: ^1.11.10
|
||||||
|
version: 1.11.10
|
||||||
marked:
|
marked:
|
||||||
specifier: ^12.0.1
|
specifier: ^12.0.1
|
||||||
version: 12.0.1
|
version: 12.0.1
|
||||||
|
@ -1453,6 +1456,10 @@ packages:
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
/dayjs@1.11.10:
|
||||||
|
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/debug@4.3.4:
|
/debug@4.3.4:
|
||||||
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==}
|
||||||
engines: {node: '>=6.0'}
|
engines: {node: '>=6.0'}
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
import * as Card from '$lib/components/ui/card';
|
import * as Card from '$lib/components/ui/card';
|
||||||
import Placeholder from '$lib/assets/img/galaxy.jpg';
|
import Placeholder from '$lib/assets/img/galaxy.jpg';
|
||||||
import Button from '../ui/button/button.svelte';
|
import Button from '../ui/button/button.svelte';
|
||||||
|
import PostMetadata from './PostMetadata.svelte';
|
||||||
|
import { faker } from '@faker-js/faker';
|
||||||
|
|
||||||
export let title: string;
|
export let title: string;
|
||||||
export let blurb: string;
|
export let blurb: string;
|
||||||
|
@ -10,8 +12,14 @@
|
||||||
|
|
||||||
<Card.Root>
|
<Card.Root>
|
||||||
<Card.Header>
|
<Card.Header>
|
||||||
<h3 class="text-4xl font-serif font-bold mb-4">{title}</h3>
|
<h3 class="text-4xl font-serif font-bold mb-4 leading-tight">{title}</h3>
|
||||||
<p class="text-muted-foreground text-xl">{blurb}</p>
|
<p class="text-muted-foreground text-xl">{blurb}</p>
|
||||||
|
<PostMetadata
|
||||||
|
primaryTags={Array.from({ length: 3 }, () => faker.hacker.noun())}
|
||||||
|
secondaryTags={Array.from({ length: 2 }, () => faker.hacker.noun())}
|
||||||
|
time={Date.now() / 1000}
|
||||||
|
length={faker.number.int(1000)}
|
||||||
|
/>
|
||||||
</Card.Header>
|
</Card.Header>
|
||||||
<Card.Content class="grid grid-cols-3 gap-6">
|
<Card.Content class="grid grid-cols-3 gap-6">
|
||||||
<img
|
<img
|
||||||
|
@ -20,7 +28,7 @@
|
||||||
class="col-span-3 md:col-span-1 rounded-2xl shadow-md"
|
class="col-span-3 md:col-span-1 rounded-2xl shadow-md"
|
||||||
/>
|
/>
|
||||||
<div class="flex flex-col justify-around col-span-3 md:col-span-2 gap-4">
|
<div class="flex flex-col justify-around col-span-3 md:col-span-2 gap-4">
|
||||||
<p class="text-primary/95 font-serif">{description}</p>
|
<p class="text-primary/95 font-serif leading-relaxed">{description}</p>
|
||||||
<Button variant="outline" href="/blog/2024/test-post" class="text-xl flex-grow sm:flex-grow-0"
|
<Button variant="outline" href="/blog/2024/test-post" class="text-xl flex-grow sm:flex-grow-0"
|
||||||
>Read More</Button
|
>Read More</Button
|
||||||
>
|
>
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
<!--
|
||||||
|
@component
|
||||||
|
|
||||||
|
This component is used to display the metadata of a blog post. It displays the primary and secondary tags, the time the post was published, and the estimated time it takes to read the post.
|
||||||
|
|
||||||
|
@props
|
||||||
|
|
||||||
|
- `primaryTags` - An array of strings representing the primary tags of the post.
|
||||||
|
- `secondaryTags` - An array of strings representing the secondary tags of the post.
|
||||||
|
- `time` - A unix epoch integer representing the time the post was published.
|
||||||
|
- `length` - An integer representing amount of words in the post.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Badge from '../ui/badge/badge.svelte';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||||
|
|
||||||
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
|
export let primaryTags: string[] = [];
|
||||||
|
export let secondaryTags: string[] = [];
|
||||||
|
export let time: number;
|
||||||
|
export let length: number;
|
||||||
|
|
||||||
|
let date = dayjs(time * 1000);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="grid grid-cols-1">
|
||||||
|
<p class="text-muted-foreground/80 my-1 text-lg">{date.format('MM/DD/YY')}</p>
|
||||||
|
<span class="flex items-center flex-wrap my-2 gap-2">
|
||||||
|
{#each primaryTags as tag}
|
||||||
|
<Badge>{tag}</Badge>
|
||||||
|
{/each}
|
||||||
|
{#each secondaryTags as tag}
|
||||||
|
<Badge variant="secondary">{tag}</Badge>
|
||||||
|
{/each}
|
||||||
|
</span>
|
||||||
|
<!-- Assuming adult silent reading rate of 238 wpm -->
|
||||||
|
<span class="text-muted-foreground text-sm mt-2">
|
||||||
|
{dayjs(date).fromNow()} | {Math.round(length / 238)} min read | {length} words
|
||||||
|
</span>
|
||||||
|
</div>
|
Loading…
Reference in a new issue